Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/main/java/org/perlonjava/app/cli/ArgumentParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -1178,9 +1178,20 @@ private static void modifyCodeBasedOnFlags(CompilerOptions parsedArgs) {
for (ModuleUseStatement moduleStatement : parsedArgs.moduleUseStatements) {
useStatements.append(moduleStatement.toString()).append("\n");
}
// Prepend the use statements to the code
// Prepend the use statements to the code.
// Wrap them in #line directives so caller() reports file=<scriptName>
// line=0 for these synthetic imports, matching real Perl's behavior
// for -M/-m. Some modules (notably Parse::RecDescent's precompiler
// mode `perl -MParse::RecDescent - grammar class`) rely on this:
// they detect the -M invocation by checking caller() in import for
// line 0 and a script file equal to '-'.
if (!useStatements.isEmpty()) {
parsedArgs.code = useStatements + parsedArgs.code;
String scriptName = parsedArgs.fileName != null ? parsedArgs.fileName : "-e";
// Escape backslashes and double quotes for the #line directive
String escapedName = scriptName.replace("\\", "\\\\").replace("\"", "\\\"");
String prefix = "#line 0 \"" + escapedName + "\"\n" + useStatements
+ "#line 1 \"" + escapedName + "\"\n";
parsedArgs.code = prefix + parsedArgs.code;
}

// Prepend rudimentary switch assignments if any
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/perlonjava/core/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public final class Configuration {
* Automatically populated by Gradle/Maven during build.
* DO NOT EDIT MANUALLY - this value is replaced at build time.
*/
public static final String gitCommitId = "b5ff444f5";
public static final String gitCommitId = "c5509171f";

/**
* Git commit date of the build (ISO format: YYYY-MM-DD).
Expand All @@ -48,7 +48,7 @@ public final class Configuration {
* Parsed by App::perlbrew and other tools via: perl -V | grep "Compiled at"
* DO NOT EDIT MANUALLY - this value is replaced at build time.
*/
public static final String buildTimestamp = "Apr 30 2026 15:38:13";
public static final String buildTimestamp = "Apr 30 2026 15:47:59";

// Prevent instantiation
private Configuration() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,11 @@ public SourceLocation getSourceLocationAccurate(int index) {
currentFileName = tokens.get(j).text;
}

if (directiveLine >= 1) {
if (directiveLine >= 0) {
// The directive applies to the following line.
// Perl allows `#line 0` (the next line becomes line 0);
// -M/-m import injection relies on this to make caller()
// report line 0, matching real Perl behavior.
lineNumber = directiveLine - 1;
}
}
Expand Down
57 changes: 57 additions & 0 deletions src/main/perl/lib/ExtUtils/MakeMaker.pm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ use Config;
# CPAN.pm and other tools expect MM->parse_version() to work after loading MakeMaker
require ExtUtils::MM;

# Set up @MY::ISA so user Makefile.PL scripts that override methods in
# `package MY;` and chain via `$self->MY::SUPER::method(...)` resolve to
# our PerlOnJava::MM::Installed defaults instead of dying with
# "Can't locate object method MY::SUPER::...". Real ExtUtils::MakeMaker
# does the equivalent (it makes MY inherit from MM).
{
no strict 'refs';
@MY::ISA = ('PerlOnJava::MM::Installed') unless @MY::ISA;
}

# Installation directory - priority: environment > Config.pm > fallback
our $INSTALL_BASE = $ENV{PERLONJAVA_LIB} || $Config{installsitelib} || _default_install_base();

Expand Down Expand Up @@ -669,6 +679,19 @@ sub _create_install_makefile {
$prereq_comment = "#\tPREREQ_PM => { " . join(", ", @prereqs) . " }\n";
}
}

# Honor user-supplied `macro => { ... }` from WriteMakefile by emitting
# extra Makefile macro definitions. LaTeXML and others stuff custom
# build variables (REVISION, REVISION_FILE, RECORD_REVISION, ...) here
# and reference them from postamble Makefile rules.
my $extra_macros_str = '';
if (ref $args->{macro} eq 'HASH') {
for my $k (sort keys %{$args->{macro}}) {
my $v = $args->{macro}{$k};
$v = '' unless defined $v;
$extra_macros_str .= "$k = $v\n";
}
}

print $fh <<"MAKEFILE";
# Makefile generated by PerlOnJava MakeMaker
Expand All @@ -682,11 +705,30 @@ NAME = $name
DISTNAME = $distname
VERSION = $version
PERL = $perl
FULLPERL = $perl
PERLRUN = \$(PERL)
FULLPERLRUN = \$(FULLPERL)
PERLRUNINST = \$(PERLRUN) -I\$(INST_ARCHLIB) -I\$(INST_LIB)
INSTALLDIRS = site
INST_LIB = $inst_lib
INST_ARCHLIB = $inst_lib
INST_LIBDIR = \$(INST_LIB)
INST_ARCHLIBDIR = \$(INST_ARCHLIB)
INSTALLSITELIB = $installsitelib
NOECHO = \@
RM_F = rm -f
RM_RF = rm -rf
CP = cp
MV = mv
MKPATH = mkdir -p
SHELL = /bin/sh
TEST_VERBOSE = 0
RECORD_REVISION = \@true
REVISION =
OLD_REVISION =
MOD_INSTALL = \$(NOECHO) \$(PERLRUN) -e "1"
UNINSTALL = \$(NOECHO) \$(PERLRUN) -e "1"
$extra_macros_str

all:: pm_to_blib pure_all pl_files blib_scripts config
\t\@echo "PerlOnJava: $name v$version built ($file_count files in ./blib)"
Expand Down Expand Up @@ -964,6 +1006,21 @@ sub new {

sub flush { 1 }

# Default no-op implementations for MakeMaker-style hooks that user
# Makefile.PL scripts commonly override in `package MY;` and chain to
# via `$self->MY::SUPER::method(...)`. We set up @MY::ISA below so
# those SUPER:: dispatches land here instead of dying.
sub postamble { '' }
sub libscan { $_[1] } # default: include this file (return $path)
sub constants { '' }
sub depend { '' }
sub dist_core { '' }
sub install { '' }
sub realclean { '' }
sub clean { '' }
sub test { '' }
sub top_targets { '' }

# Methods needed by File::ShareDir::Install postamble
sub oneliner {
my ($self, $code, $switches) = @_;
Expand Down
Loading