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