-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile.PL
238 lines (181 loc) · 6.2 KB
/
Makefile.PL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
use warnings;
use strict;
use Pod::Usage;
use Getopt::Long;
use ExtUtils::MakeMaker qw(WriteMakefile prompt);
use 5.006; # for "no warnings" -- sorry!
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
my %prereq = (
'Data::Dumper' => 0,
'Scalar::Util' => 0,
);
## Poor man's optional deps.
sub test_for
{
my $mod = shift;
eval "require $mod";
if ($@) {
my $resp = prompt("@_. Install $mod (y/n)? ", 'n');
$prereq{$mod} = 0 if $resp =~ /^y/i;
}
}
my $ELISP_FIND_SITELISP = <<'END_ELISP';
(dolist (x load-path) (princ x) (terpri))
END_ELISP
my $ELISP_FIND_INFODIR = <<'END_ELISP';
(progn
(require (quote info))
(princ (car Info-default-directory-list)))
END_ELISP
my ($EMACS, $SITE_LISP, $INSTALL_INFO, $INFO_DIR, $HELP);
sub escape_path
{
my ($path) = @_;
$path =~ s/([$?* ])/\\$1/g; # escape special characters
$path =~ s{/+$}{}; # remove trailing forward-slashes
return $path;
}
sub prompt_for_emacs
{
# try to compile and install Elisp files, but don't die if we can't.
my ($sysemacs) = grep { defined && -x }
$ENV{EMACS}, glob '/usr/bin{/local,}/emacs';
$sysemacs ||= q{emacs};
my $emacs = prompt("Where is your emacs? ", $sysemacs);
# Make sure emacs is a valid string/program path...
return undef unless $emacs;
# Make sure -x is passed an absolute path...
unless ( $emacs =~ m{^/} && -x $emacs ) {
warn "$emacs is not executable! Undefined.\n";
return undef;
}
return escape_path( $emacs );
}
# Runs some elisp code with emacs via the command line.
# We must set $EMACS before running this... if it is an untrue value
# then we return an empty list or string, depending on what caller wants.
sub run_elisp
{
my ($elisp) = @_;
return wantarray ? qw// : q{} unless $EMACS;
return `$EMACS --batch --eval '$elisp' 2>/dev/null`;
}
sub prompt_for_sitelisp
{
my @lp = run_elisp( $ELISP_FIND_SITELISP );
chomp @lp;
my $site_lisp;
if ( scalar @lp ) {
($site_lisp) = grep { /site-lisp$/ && -d $_ } @lp;
}
$site_lisp = prompt("Elisp install directory?", $site_lisp);
# We don't check if the directory exists, because we can create it...
return escape_path( $site_lisp );
}
sub prompt_for_infodir
{
my $info_dir = run_elisp( $ELISP_FIND_INFODIR );
chomp $info_dir;
# pass prompt undef so it will not display brackets if $info_dir is ""
$info_dir = prompt("Info directory?", $info_dir || undef);
return escape_path( $info_dir );
}
# Append info page and elisp installation to the end of the install
# section in the Makefile...
sub MY::postamble
{
# Make an entry for Sepia.html as a target to make things easier...
my $maketxt = <<'END_MAKETXT';
all :: Sepia.html
Sepia.html : sepia.texi
makeinfo --no-split --no-headers --html sepia.texi -o Sepia.html
END_MAKETXT
$maketxt .= <<"END_MAKETXT";
install ::
END_MAKETXT
if ( $INFO_DIR ) { $maketxt .= <<"END_MAKETXT" }
install -d -m755 \$(DESTDIR)$INFO_DIR
install -m644 sepia.info \$(DESTDIR)$INFO_DIR
$INSTALL_INFO \$(DESTDIR)$INFO_DIR/sepia.info \$(DESTDIR)$INFO_DIR/dir
END_MAKETXT
if ( $SITE_LISP ) {
$maketxt .= <<"END_MAKETXT"
install -d -m755 \$(DESTDIR)$SITE_LISP
install -m644 *.el *.elc \$(DESTDIR)$SITE_LISP
END_MAKETXT
} else {
print <<'END_MSG'
======================================================================
To actually use this package, you need to move the Emacs Lisp files
somewhere Emacs will find them.
You may also want to install the HTML documentation somewhere
appropriate to your system.
======================================================================
END_MSG
}
# Create a new target for compiled elisp (.elc) files...
# Allow the compilation to fail (it is prefixed with "-")...
if ( $EMACS ) {
$maketxt .= <<"EOS";
\%.elc : \%.el
- $EMACS -L '$ENV{PWD}' --batch -f batch-byte-compile \$? 2>/dev/null
all :: sepia-snippet.elc sepia.elc sepia-cpan.elc sepia-tree.elc \\
sepia-w3m.elc sepia-ido.elc
EOS
}
return $maketxt;
}
GetOptions( 'emacs=s' => \$EMACS,
'lisp=s' => \$SITE_LISP,
'info=s' => \$INFO_DIR,
'help' => \$HELP,
);
exit pod2usage( '-verbose' => 1 ) if $HELP;
test_for 'Devel::Peek', 'Printing internals requires Devel::Peek';
test_for 'Devel::Size', 'Printing variable sizes requires Devel::Size';
test_for 'IO::Scalar', 'Printing internals requires IO::Scalar because Devel::Peek sucks';
test_for 'Lexical::Persistence', 'Strict mode requires Lexical::Persistence';
test_for 'LWP::Simple', 'CPAN documentation browsing requires LWP::Simple';
test_for 'Module::CoreList', 'sepia-core-version requires Module::CoreList';
test_for 'Module::Info', 'Required for some Emacs functions';
test_for 'PadWalker', 'Stack/lexical inspection requires PadWalker >= 1.0';
test_for 'BSD::Resource', 'Detailed command timing';
test_for 'Time::HiRes', 'Basic command timing';
# test_for 'Pod::Webserver', 'Pod::Webserver creates nice documentation.';
# test_for 'Scope::Upper', 'Required for return-from-context';
$INSTALL_INFO = 'install-info';
$EMACS ||= prompt_for_emacs()
or warn "Disabling elisp compilation and dir detection.\n";
$SITE_LISP ||= prompt_for_sitelisp();
$INFO_DIR ||= prompt_for_infodir();
$INSTALL_INFO ||= prompt("install-info program?", 'install-info')
if $INFO_DIR;
WriteMakefile(
NAME => 'Sepia',
VERSION_FROM => 'lib/Sepia.pm', # finds $VERSION
PREREQ_PM => \%prereq,
EXE_FILES => ['sepl'],
AUTHOR => "Sean O'Rourke <seano\@cpan.org>",
ABSTRACT => 'Simple Emacs-Perl InterAction',
clean => { FILES => '*.elc' },
);
__END__
=head1 SYNOPSIS
# prompts for paths
perl Makefile.PL
# doesn't prompt for paths
perl Makefile.PL --emacs /usr/bin/emacs \
--lisp /usr/share/emacs/site-lisp/sepia \
--info /usr/share/info
=head1 OPTIONS
=over 4
=item B<--emacs>
Specifies the path to emacs.
=item B<--lisp>
Specifies the directory to install the elisp files to.
=item B<--info>
Specifies the directory to install the texinfo files to.
=item B<--help>
Display this help information.
=back