diff --git a/lib/ExtUtils/MM_Any.pm b/lib/ExtUtils/MM_Any.pm index 45136821c..6d40bc4ff 100644 --- a/lib/ExtUtils/MM_Any.pm +++ b/lib/ExtUtils/MM_Any.pm @@ -1852,7 +1852,7 @@ sub special_targets { my $make_frag = <<'MAKE_FRAG'; .SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT) -.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir pure_all subdirs clean_subdirs makemakerdflt manifypods realclean_subdirs subdirs_dynamic subdirs_pure_nolink subdirs_static subdirs-test_dynamic subdirs-test_static test_dynamic test_static +.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir pure_all subdirs clean_subdirs makemakerdflt manifypods realclean_subdirs subdirs_dynamic subdirs_pure_nolink subdirs_static subdirs-test_dynamic subdirs-test_static test_dynamic test_static sharedir MAKE_FRAG @@ -1935,6 +1935,8 @@ sub init_INST { $self->{INST_ARCHAUTODIR} = $self->catdir('$(INST_ARCHLIB)', 'auto', '$(FULLEXT)'); + $self->{INST_SHARE} ||= $self->catdir('$(INST_LIB)', 'auto', 'share'); + $self->{INST_SCRIPT} ||= $self->catdir($Curdir,'blib','script'); $self->{INST_MAN1DIR} ||= $self->catdir($Curdir,'blib','man1'); @@ -2969,6 +2971,37 @@ sub postamble { ""; } +sub sharedir { + my ($self, %share) = @_; + return '' unless %share; + + my %files; + $self->_sharedir_find_files(\%files, $share{dist}, [qw/ $(INST_SHARE) dist $(DISTNAME) /], \%share) if $share{dist}; + for my $module (keys %{ $share{module} || {} }) { + my $destination = [ qw/$(INST_SHARE) module/, $module ]; + $self->_sharedir_find_files(\%files, $share{module}{$module}, $destination, \%share); + } + my $pm_to_blib = $self->oneliner(q{pm_to_blib({@ARGV}, '$(INST_LIB)')}, ['-MExtUtils::Install']); + return "\npure_all :: sharedir\n\nsharedir : \n" . join '', map { "\t\$(NOECHO) $_\n" } $self->split_command($pm_to_blib, %files); +} + +sub _sharedir_find_files { + my ($self, $files, $source, $sink, $options) = @_; + File::Find::find({ + wanted => sub { + if (-d) { + $File::Find::prune = 1 if $options->{skip_dotdir} && /^\./; + return; + } + return if $options->{skip_dotfile} && /^\./; + my $file = $self->abs2rel($_, $source); + $files->{$_} = $self->catfile(@{$sink}, $file); + }, + no_chdir => 1, + }, $source); + return; +} + =begin private =head3 _PREREQ_PRINT diff --git a/lib/ExtUtils/MM_Unix.pm b/lib/ExtUtils/MM_Unix.pm index fe385984f..f8d5f5adc 100644 --- a/lib/ExtUtils/MM_Unix.pm +++ b/lib/ExtUtils/MM_Unix.pm @@ -510,6 +510,7 @@ INST_ARCHLIBDIR = $self->{INST_ARCHLIBDIR} INST_AUTODIR = $self->{INST_AUTODIR} INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR} +INST_SHARE = $self->{INST_SHARE} INST_STATIC = $self->{INST_STATIC} INST_DYNAMIC = $self->{INST_DYNAMIC} diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index e8c3808b3..b63ccb461 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -129,6 +129,7 @@ my %Special_Sigs = ( macro => 'HASH', postamble => 'HASH', realclean => 'HASH', + sharedir => 'HASH', test => 'HASH', tool_autosplit => 'HASH', ); @@ -351,7 +352,7 @@ sub full_setup { makemakerdflt dist macro depend cflags const_loadlibs const_cccmd - post_constants + post_constants sharedir pasthru @@ -3033,6 +3034,16 @@ L if you have one. {FILES => '$(INST_ARCHAUTODIR)/*.xyz'} +=item sharedir + +This sets the sharedirs to install. + + {dist => 'share', module => { Foo => 'foo', ... }} + +The C key sets the source for the dist specific sharedir content. The +C key is a hash mapping module names to their specific sharedir. The +keys C and C will make it skip dot-directories + =item test Specify the targets for testing. diff --git a/t/sharedir.t b/t/sharedir.t new file mode 100644 index 000000000..d0e286893 --- /dev/null +++ b/t/sharedir.t @@ -0,0 +1,101 @@ +use strict; +use warnings; + +use Test::More tests => 6; +use File::Temp 'tempdir'; + +use File::Spec::Functions qw/catfile catdir/; +use File::Path 'mkpath'; +use Cwd 'cwd'; + +use IPC::Open3; +use Symbol 'gensym'; +use Env qw(@PERL5LIB $PERL_MM_OPT); + +# ABSTRACT: Test basic behaviour + +my $install = tempdir(); +my $pwd = cwd; + +# Make sure install target is prepped. +unshift @PERL5LIB, $install, catdir($pwd, 'lib'); +$PERL_MM_OPT = "INSTALL_BASE=$install"; + +# Prep the source tree +my $source = tempdir(); + +mkdir catdir($source, 'lib'); +spew(catfile($source, 'lib', 'TestDist.pm'), "package TestDist;\n\$VERSION = '1.000';\n1;\n"); + +my $share = catdir($source, 'share'); +my $dotdir = catdir($share, qw/dots .dotdir/); + +mkpath($dotdir); +spew(catfile($dotdir, 'normalfile'), 'This is a normal file'); +spew(catfile($dotdir, '.dotfile'), 'This is a dotfile'); +spew(catfile($share, 'dots', '.dotfile'), 'This is a dotfile'); +spew(catfile($share, 'normalfile'), 'This is a normal file'); + +spew(catfile($source, 'Makefile.PL'), <<'MAKEFILE'); +use strict; +use warnings; + +use ExtUtils::MakeMaker; + +my %Args = ( + ABSTRACT => "Test Module", + DISTNAME => "TestDist", + NAME => "TestDist", + PREREQ_PM => {}, + sharedir => { + dist => 'share', + }, +); + +WriteMakefile(%Args); + +MAKEFILE + +chdir $source; +END { chdir $pwd } + +sub run_ok { + my (@command) = @_; + my $desc = join ' ', @command; + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my ($inh, $outh, $errh) = (undef, undef, gensym); + my $pid = open3($inh, $outh, $errh, @command) or do { + fail "Command $desc: $!"; + return; + }; + close $inh; + + my $out = do { local $/; <$outh> }; + my $err = do { local $/; <$errh> }; + + waitpid $pid, 0 or die 'Couldn\'t waitpid'; + return cmp_ok( $?, '==', 0, "Command $desc" ) || note explain { 'stdout' => $out, 'stderr' => $err, exit => $? } +} + +# Testing happens here: +SKIP: { + run_ok($^X, 'Makefile.PL'); + run_ok('make'); + run_ok('make', 'install'); + + my $dir = catdir($install, qw/lib perl5 auto share dist TestDist/); + ok(-d $dir, 'Sharedir has been created') or diag $dir; + open my $fh, '<', 'Makefile'; + diag <$fh>; + ok(-e catfile($dir, 'normalfile'), 'File in sharedir has been created'); + ok(-e catfile($dir, qw/dots .dotdir .dotfile/), 'A dotfile in a dotdir installed'); +} + +sub spew { + my ($filename, $content) = @_; + open my $fh, '>', $filename or die "Couldn't open $filename: $!"; + print $fh $content or die "Couldn't write to $filename: $!"; + close $fh or die "Couldn't close $filename: $!"; + return; +}