Skip to content

Module::Build support#327

Merged
fglock merged 13 commits into
masterfrom
feature/module-build-support
Mar 18, 2026
Merged

Module::Build support#327
fglock merged 13 commits into
masterfrom
feature/module-build-support

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Mar 17, 2026

Summary

Adds support for installing Module::Build via jcpan. This enables jcpan install Module::Build to complete successfully.

Key fixes:

  1. Fork-open emulation - Emulates Perl's open FH, "-|" pattern at runtime without requiring fork(). When this pattern is detected, the subsequent exec @cmd captures command output and returns it as the subroutine's result. This transparently supports Module::Build's _backticks() without patches.

  2. Parser filehandle detection - Imported subroutines are no longer mistakenly parsed as filehandles (fixes print myconfig)

  3. jperl classpath handling - Empty CLASSPATH no longer adds current directory

  4. Config::myconfig() - Returns perl configuration string needed by Module::Build

  5. File test on underscore - Handle null lastBasicAttr when using _ after testing JAR paths

  6. File::Path relative paths - Fix _make_path_perl to preserve relative paths (was turning _build into /_build)

  7. system()/exec() array flattening - Properly expand array arguments into individual command args

  8. File::Spec jar: paths - Recognize jar: paths as absolute to prevent CPAN.pm from mangling @inc

  9. File::Spec::catdir() - Preserve leading / for absolute paths when first splitdir element is empty

  10. POSIX::access() - Return "0 but true" on success to match Perl semantics (numerically 0, boolean true)

  11. ExtUtils circular dependencies - Fix MM.pm and MY.pm circular dependency

  12. SeekableJarHandle - JAR resources now support seek (needed by Module::Metadata)

New modules/features:

  • lib.pm - @inc manipulation
  • File::Compare.pm - File comparison
  • ExtUtils::Manifest - MANIFEST handling
  • Site installation paths in Config.pm (installsitelib, etc.)
  • POSIX access constants (F_OK, R_OK, W_OK, X_OK)
  • Fork-open state management (ForkOpenState, ForkOpenCompleteException)

Design Documentation

See dev/design/fork_open_emulation.md for detailed documentation of the fork-open emulation approach.

Test plan:

  • make passes all unit tests
  • jperl -MModule::Build -e 'print "ok\n"' works
  • Module::Build installs without patches via jcpan install Module::Build

Generated with Devin

fglock and others added 11 commits March 17, 2026 22:27
- croak-locations.t now passes all 29 tests (was failing 2)
- Updated test results: 65/71 (91.5%), 808/839 subtests (96.3%)
- All remaining failures are expected (DESTROY/weak refs)
- Marked Phase 38 as complete

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
- Update YAML.pm version from 0.01 to 1.31
- CPAN.pm requires >= 0.60; this silences the "YAML version too low" warning
- Our YAML.pm wraps YAML::PP which provides full functionality
- Update cpan_client.md: mark YAML and DistnameInfo issues as resolved

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
- Fix JVM backend Dereference.java to check isStrictOptionEnabled for
  ${"name"}[index] syntax, using arrayDerefGetNonStrict when appropriate
- Add bytecode interpreter support for symbolic array element access
- Add File::Compare.pm for Module::Build dependency
- Add VERSION to File::Spec (3.95) and Encode (3.21) for CPAN detection
- Update YAML.pm version to 1.31 to silence CPAN.pm warning

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
Key fixes:
- FileHandle parser: Check for CODE ref before treating bareword as filehandle
  This fixes "print myconfig" where myconfig is an imported subroutine
- jperl: Fix CLASSPATH handling to avoid adding current directory
  Empty CLASSPATH was causing ":$JAR_PATH" which added "." to classpath
- Config.pm: Add myconfig() function for Module::Build compatibility
- Module::Build::Base stub: Override have_forkpipe() to disable fork pipes
  JVM cannot support fork(), so Module::Build uses backticks instead

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
Required by Module::Build for MANIFEST file handling.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
1. FileTestOperator: Handle null lastBasicAttr when using underscore (_)
   filehandle after testing a JAR path. Fall back to re-testing the file.

2. File::Path: Fix _make_path_perl to handle relative paths correctly.
   Previously "_build" became "/_build" (absolute). Now relative paths
   are preserved.

These fixes allow Module::Build Build.PL to complete successfully.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
When passing an array to system(@cmd) or exec(@cmd), each array element
should be a separate command argument. Previously, the array was being
stringified (concatenating elements without separator) instead of
expanded into individual arguments.

Added flattenToStringList() helper to properly expand RuntimeArray and
RuntimeList elements into individual string arguments.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
- Fix ExtUtils::MakeMaker version to 7.70 (remove _perlonjava suffix
  that broke version comparison)
- Add Fcntl VERSION (1.15) to fix version check errors
- Add lib.pm (simplified version for @inc manipulation)
- Sync Text::Abbrev, IO::Dir, JSON::PP, utf8, vars from perl5
- Mark File::Temp as protected (keep custom PerlOnJava implementation)
- Update sync config with new modules

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
- Add SeekableJarHandle for JAR resources with seek support
  (needed by Module::Metadata for encoding detection)
- Fix File::Spec to recognize jar: paths as absolute
  (prevents CPAN.pm from mangling @inc paths)
- Fix circular dependency in ExtUtils::MM and ExtUtils::MY
  (removed unnecessary use ExtUtils::MakeMaker)

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
- Fix catdir() to preserve leading "/" for absolute paths when first
  element from splitdir() is empty (representing root directory)
- Fix POSIX::access() to return "0 but true" on success instead of 0,
  matching Perl's semantics where it's false numerically but true in
  boolean context
- Add POSIX access constants F_OK, R_OK, W_OK, X_OK and access() function
- Add site installation paths to Config.pm for Module::Build

This allows Module::Build to install successfully via jcpan.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
@fglock fglock changed the title WIP: Module::Build support Module::Build support Mar 18, 2026
@fglock fglock marked this pull request as ready for review March 18, 2026 05:52
fglock and others added 2 commits March 18, 2026 07:24
Implements runtime emulation of Perl's fork-open pattern (open FH, "-|")
which normally requires fork(). Since JVM cannot fork, we detect this
pattern at runtime and handle it specially:

1. open FH, "-|" without command sets pending state, returns 0 (child)
2. exec @cmd detects pending state, runs command, captures output
3. Throws ForkOpenCompleteException caught by RuntimeCode.apply()
4. Subroutine returns captured output as if parent branch executed

This transparently supports Module::Build's _backticks() pattern without
requiring any patches to Module::Build itself.

New files:
- ForkOpenState.java: Thread-local pending state tracking
- ForkOpenCompleteException.java: Control flow exception
- dev/design/fork_open_emulation.md: Design documentation

Modified:
- IOOperator.open(): Detect 2-arg "-|" and set pending state
- SystemOperator.exec(): Complete pending fork-open with captured output
- RuntimeCode.apply(): Catch exception and return captured output

Limitation: Only works when fork-open is inside a subroutine.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <noreply@cognition.ai>
@fglock fglock merged commit f1ce05b into master Mar 18, 2026
2 checks passed
@fglock fglock deleted the feature/module-build-support branch March 18, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant