]> Dogcows Code - chaz/p5-Alien-ZMQ/blob - inc/My/Build.pm
require perl 5.10.1 for File::Path::make_path
[chaz/p5-Alien-ZMQ] / inc / My / Build.pm
1 package My::Build;
2
3 use v5.10.1;
4 use warnings FATAL => 'all';
5 use strict;
6 use utf8;
7
8 use Archive::Tar;
9 use Cwd qw/realpath/;
10 use Digest::SHA qw/sha1_hex/;
11 use File::Path qw/remove_tree/;
12 use File::Spec::Functions qw/catdir catfile/;
13 use IPC::Run qw/run/;
14 use LWP::Simple qw/getstore RC_OK/;
15 use Module::Build;
16
17 use base 'Module::Build';
18
19 sub ACTION_code {
20 my $self = shift;
21
22 $self->SUPER::ACTION_code;
23
24 return if -e 'build-zeromq';
25 $self->add_to_cleanup('build-zeromq');
26
27 my %args = $self->args;
28 my %vars;
29
30 $self->have_c_compiler or die "C compiler not found";
31
32 unless (exists $args{'zmq-skip-probe'}) {
33 say "Probing...";
34 %vars = $self->probe_zeromq;
35 }
36
37 if ($vars{inc_version} && $vars{lib_version} && $vars{inc_dir} && $vars{lib_dir}) {
38 say "Found ØMQ $vars{lib_version}; skipping installation";
39 } else {
40 say "ØMQ not found; building from source...";
41 %vars = $self->install_zeromq;
42 }
43
44 # write vars to ZMQ.pm
45 my $module = catfile qw/blib lib Alien ZMQ.pm/;
46 open my $LIB, '<', $module or die "Cannot read module";
47 my $lib = do { local $/; <$LIB> };
48 close $LIB;
49 $lib =~ s/^sub inc_dir.*$/sub inc_dir { "$vars{inc_dir}" }/m;
50 $lib =~ s/^sub lib_dir.*$/sub lib_dir { "$vars{lib_dir}" }/m;
51 $lib =~ s/^sub inc_version.*$/sub inc_version { v$vars{inc_version} }/m;
52 $lib =~ s/^sub lib_version.*$/sub lib_version { v$vars{lib_version} }/m;
53 my @stats = stat $module;
54 chmod 0644, $module;
55 open $LIB, '>', $module or die "Cannot write config to module";
56 print $LIB $lib;
57 close $LIB;
58 chmod $stats[2], $module;
59
60 open my $TARGET, '>', "build-zeromq";
61 print $TARGET time, "\n";
62 close $TARGET;
63 }
64
65 sub probe_zeromq {
66 my $self = shift;
67 my $cb = $self->cbuilder;
68 my %config = $cb->get_config;
69
70 my $src = "test-$$.c";
71 open my $SRC, '>', $src;
72 print $SRC <<END;
73 #include <stdio.h>
74 #include <zmq.h>
75 int main(int argc, char* argv[]) {
76 int major, minor, patch;
77 zmq_version(&major, &minor, &patch);
78 printf("%d.%d.%d %d.%d.%d",
79 ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH,
80 major, minor, patch);
81 return 0;
82 }
83 END
84 close $SRC;
85
86 my @inc_search;
87 my @lib_search;
88
89 my $cflags = $self->args('zmq-cflags');
90 my $libs = $self->args('zmq-libs');
91
92 my $pkg_version;
93
94 my $pkg_config = $ENV{PKG_CONFIG_COMMAND} || "pkg-config";
95 for my $pkg (qw/libzmq zeromq3/) {
96 $pkg_version = `$pkg_config $pkg --modversion`;
97 chomp $pkg_version;
98 next unless $pkg_version;
99
100 $cflags ||= `$pkg_config $pkg --cflags`;
101 $libs ||= `$pkg_config $pkg --libs`;
102
103 # use -I and -L flag arguments as extra search directories
104 my $inc = `$pkg_config $pkg --cflags-only-I`;
105 push @inc_search, map { s/^-I//; $_ } $cb->split_like_shell($inc);
106 my $lib = `$pkg_config $pkg --libs-only-L`;
107 push @lib_search, map { s/^-L//; $_ } $cb->split_like_shell($lib);
108
109 last;
110 }
111
112 my $obj = eval {
113 $cb->compile(source => $src, include_dirs => [@inc_search], extra_compiler_flags => $cflags);
114 };
115 unlink $src;
116 return unless $obj;
117
118 my $exe = eval {
119 $cb->link_executable(objects => $obj, extra_linker_flags => $libs);
120 };
121 unlink $obj;
122 return unless $exe;
123
124 my $out = `./$exe`;
125 unlink $exe;
126 my ($inc_version, $lib_version) = $out =~ /(\d\.\d\.\d) (\d\.\d\.\d)/;
127
128 # query the compiler for include and library search paths
129 push @lib_search, map {
130 my $path = $_;
131 $path =~ s/^.+ =?//;
132 $path =~ s/\n.*$//;
133 -d $path ? realpath($path) : ();
134 } split /:/, `$config{cc} -print-search-dirs`;
135 push @inc_search, map {
136 my $path = $_;
137 $path =~ s/lib(32|64)?$/include/;
138 $path;
139 } @lib_search;
140
141 # search for the header and library files
142 my ($inc_dir) = grep { -f catfile($_, "zmq.h") } @inc_search;
143 my ($lib_dir) = grep { -f catfile($_, $cb->lib_file("libzmq")) } @lib_search;
144
145 (
146 inc_version => $inc_version,
147 lib_version => $lib_version,
148 pkg_version => $pkg_version,
149 inc_dir => $inc_dir,
150 lib_dir => $lib_dir,
151 );
152 }
153
154 sub install_zeromq {
155 my $self = shift;
156 my $cb = $self->cbuilder;
157
158 my $version = $self->notes('zmq-version');
159 my $sha1 = $self->notes('zmq-sha1');
160 my $archive = "zeromq-$version.tar.gz";
161
162 say "Downloading ØMQ $version source archive from download.zeromq.org...";
163 getstore("http://download.zeromq.org/$archive", $archive) == RC_OK
164 or die "Failed to download ØMQ source archive";
165
166 say "Verifying...";
167 my $sha1sum = Digest::SHA->new;
168 open my $ARCHIVE, '<', $archive or die "Can't open source archive";
169 binmode $ARCHIVE;
170 $sha1sum->addfile($ARCHIVE);
171 close $ARCHIVE;
172 $sha1sum->hexdigest eq $sha1 or die "Source archive checksum mismatch";
173
174 say "Extracting...";
175 Archive::Tar->new($archive)->extract;
176 unlink $archive;
177
178 my $prefix = catdir($self->install_destination("lib"), qw/auto share dist Alien-ZMQ/);
179 my $basedir = $self->base_dir;
180 my $datadir = catdir($basedir, "share");
181 my $srcdir = catdir($basedir, "zeromq-$version");
182 chdir $srcdir;
183
184 say "Patching...";
185 for my $patch (glob("$basedir/files/zeromq-$version-*.patch")) {
186 run [qw/patch -p1/], '<', $patch or die "Failed to patch ØMQ";
187 }
188
189 say "Configuring...";
190 my @config = $cb->split_like_shell($self->args('zmq-config') || "");
191 $cb->do_system(qw/sh configure CPPFLAGS=-Wno-error/, "--prefix=$prefix", @config)
192 or die "Failed to configure ØMQ";
193
194 say "Compiling...";
195 $cb->do_system("make") or die "Failed to make ØMQ";
196
197 say "Installing...";
198 $cb->do_system(qw|make install prefix=/|, "DESTDIR=$datadir")
199 or die "Failed to install ØMQ";
200
201 chdir $basedir;
202 remove_tree($srcdir);
203
204 (
205 inc_version => $version,
206 lib_version => $version,
207 inc_dir => catdir($prefix, "include"),
208 lib_dir => catdir($prefix, "lib"),
209 );
210 }
211
212 1;
This page took 0.041529 seconds and 4 git commands to generate.