1# Makefile.PL for Perl module WWW::Curl 2# Check out the README file for more information. 3 4use inc::Module::Install; 5 6name 'WWW-Curl'; 7abstract 'Perl extension interface for libcurl'; 8author 'Cris Bailiff <c.bailiff+curl at devsecure.com>'; 9license 'mit'; 10perl_version '5.006001'; 11no_index directory => 'template'; 12repository 'http://github.com/szbalint/WWW--Curl'; 13# This is a hack. If you have libcurl installed, just specify curl.h below 14# and comment out this line. 15if ($^O ne 'MSWin32') { 16 if (!$ENV{CURL_CONFIG}) { 17 requires_external_bin 'curl-config'; 18 } 19} else { 20 print "Sorry, no automated install is available on Windows,\n". 21 "please see the README.Win32 file on instructions for a manual install.\n"; 22 exit(0); 23} 24 25my $curl_config = $ENV{CURL_CONFIG} || 'curl-config'; 26 27my $vernum = `${curl_config} --vernum`; chomp $vernum; 28my $version = `${curl_config} --version`; chomp $version; 29 30my $minimum_ver = hex("070a08"); 31 32if ($vernum && hex($vernum) <= $minimum_ver) { 33 print "Your currently installed libcurl version - $version - is too old.\n". 34 "This module doesn't seek compatibility with versions older than 7.10.8\n". 35 "Proceed manually if you know what you're doing.\n"; 36 exit(0); 37} 38 39print "The version is $version\n"; 40 41my @includes = qw(); 42my ($cflags,$lflags, $ldflags) = ('','',''); 43 44# You may need to specify where to find curl.h on your platform 45# These are guesses only, in case curl-config is not telling us. 46 47if ($^O ne 'MSWin32') { 48 push @includes, qw( 49 /usr/include 50 /usr/local/curl/include 51 /usr/local/include/curl 52 ../../include 53 ../curl/include 54 ); 55} 56 57# 58# Get curl to tell us where it is, if we can. 59# 60 61if ($^O ne 'MSWin32') { 62 $cflags = `${curl_config} --cflags`; 63 $lflags = `${curl_config} --libs`; 64} 65 66# can't find link flags, make some guesses 67if (!defined($lflags)) { 68 $lflags="-lcurl"; 69 print "Guessing your linker flags as: $lflags\n"; 70} 71 72my ($flag) = ($cflags =~ m/-I(\S+)/); 73 74if (defined $flag) { 75 unshift @includes, $flag; # first guess 76} 77 78# try the path given on the command line, if any 79if (defined($ARGV[0])) { 80 unshift @includes, $ARGV[0]; 81}; 82 83my $curl_d = ""; 84my $curl_h; 85 86# otherwise try a list of common locations 87foreach my $try (@includes) { 88 if (-f $try . "/curl/curl.h") { 89 $curl_d = $try; 90 $curl_h = $try . "/curl/curl.h"; 91 last; 92 } 93} 94 95if (!defined($curl_h)) { 96 die "Cannot find curl.h - cannot build constants files - see Makefile.PL"; 97} else { 98 my %constants; 99 $curl_d = "-I" . $curl_d; 100 print "Found curl.h in $curl_h\n"; 101 my @syms; 102 my $has_cpp = 0; 103 my @skiplist = qw/ 104 CURL_DID_MEMORY_FUNC_TYPEDEFS 105 CURL_STRICTER 106 CURLINC_CURL_H 107 CURL_WIN32 108 CURLOPT 109 /; 110 open(H_IN, "-|", "cpp", $curl_h) and $has_cpp++; 111 unless ($has_cpp) { 112 warn "No working cpp ($!). Parsing curl.h in Perl"; 113 open(H_IN, "<", $curl_h) or die("Can't open curl.h at path $curl_h, because: ".$!); 114 } 115 while ( <H_IN> ) { 116 if ( /enum\s+(\S+\s+)?{/ .. /}/ ) { 117 s/^\s+//; 118 next unless /^CURL/; 119 chomp; 120 s/^(CURL[A-Za-z0-9_]*_) ([A-Za-z0-9_])/$1$2/; # Strip intervening space from ISO CPP macro 121 s/[,\s].*//; 122 s/=.*$//; 123 next unless /^\w+$/; 124 push @syms, $_; 125 } 126 } 127 close H_IN; 128 open (H, "<", $curl_h) or die ("Cannot open $curl_h: ".$!); 129 while(<H>) { 130 if (/^#define (CURL[A-Za-z0-9_]*)/) { 131 next if $1 ~~ @skiplist; 132 push @syms, $1; 133 } 134 } 135 close H; 136 137 for my $e (sort @syms) { 138 if($e =~ /(OBSOLETE|^CURL_EXTERN|_LAST\z|_LASTENTRY\z)/) { 139 next; 140 } 141 my ($group) = $e =~ m/^([^_]+_)/; 142 $constants{$group}->{$e} = $e; 143 } 144 unless ($has_cpp) { 145 open(CURL_H, "<" . $curl_h) or die "Can't open curl.h\n"; 146 while (<CURL_H>) { 147 if ($_ =~ m/CINIT\(/ and $_ !~ m/#/) { 148 my ($option, $type, $code) = m/.*CINIT\((\w*)\s*,\s*(\w+)\s*,\s*(\d+).*/; 149 $constants{"CURLOPT_"}->{"CURLOPT_".$option} = "CURLOPT_".$option; 150 } elsif ($_ =~ m/^#define CURLOPT_\w+\s+CURLOPT_\w+/) { 151 my ($option, $value) = 152 m/^#define CURLOPT_(\w+)\s+CURLOPT_(\w+)/; 153 $constants{"CURLOPT_"}->{"CURLOPT_".$option} = "CURLOPT_".$value; 154 } elsif ($_ =~ m/^\s*((CURLINFO_|CURLSHOPT_|CURLE_)\w+)/) { 155 $constants{$2}->{$1}= $1; 156 } elsif ($_ =~ m/^\s*((CURL_)(?:\w+))(?:[,\s]*)(?:\/\*.*)?$/) { 157 $constants{$2}->{$1} = $1; 158 } elsif ($_ =~ m/^\s*((CURLPROXY_)(?:\w+))\s*=\s*\d+/) { 159 $constants{$2}->{$1} = $1; 160 } elsif ($_ =~ m/CFINIT\(/ and $_ !~ m/#/) { 161 my ($option) = m/.*CFINIT\((\w*)\s*.*/; 162 $constants{"CURLFORM_"}->{"CURLFORM_".$option} = "CURLFORM_".$option; 163 } 164 } 165 close(CURL_H); 166 } 167 print "Building curlopt-constants.c for your libcurl version\n"; 168 169 open(CURL_XS, ">curlopt-constants.c") 170 or die "Can't write curlopt-constants.c\n"; 171 172 # boilerplate xs constant function here 173 print CURL_XS <<HERE 174static int 175constant(const char *name) 176{ 177 errno = 0; 178HERE 179 ; 180for my $group (reverse sort keys %constants) { 181 my $grouplength = length($group); 182 my $groupref = $constants{$group}; 183 my @constants = keys %{$constants{$group}}; 184 print CURL_XS <<HERE2 185 186 if (strncmp(name, "$group", $grouplength) == 0) { 187 name += $grouplength; 188 switch (*name) { 189HERE2 190 ; 191 192 for my $next_initial ('A' .. 'Z') { 193 print CURL_XS " case '$next_initial':\n"; 194 my $count = 0; 195 foreach my $option (sort @constants) { 196 my $remainder = substr($option, length($group), length($option)); 197 my $initial = substr($remainder, 0, 1); 198 if ($next_initial eq $initial) { 199 200 print CURL_XS 201" if (strEQ(name, \"$remainder\")) return "."$groupref->{$option};\n"; 202 203 $count++; 204 } 205 } 206 if ($count or $next_initial eq 'Z') { 207 print CURL_XS " break;\n"; 208 } 209 } 210 211 print CURL_XS " };\n"; 212 print CURL_XS " }\n"; 213} 214 215 print CURL_XS <<HERE 216 217 errno = EINVAL; 218 return 0; 219} 220HERE 221 ; 222 223 close(CURL_XS); 224 225 print "Building Easy.pm constants for your libcurl version\n"; 226 227 open(EASY_PM, ">lib/WWW/Curl/Easy.pm") or die "Can't create lib/WWW/Curl/Easy.pm\n"; 228 open(EASY_PM_IN, "template/Easy.pm.tmpl") or die "Can't read template/Easy.pm.tmpl\n"; 229 while (my $line = <EASY_PM_IN>) { 230 if ($line !~ m/^\@CURLOPT_INCLUDE\@/) { 231 print EASY_PM $line; 232 } else { 233 for my $group (reverse sort keys %constants) { 234 for my $option (sort keys %{$constants{$group}}) { 235 next unless $option; 236 print EASY_PM $option."\n"; 237 } 238 } 239 } 240 } 241 close(EASY_PM); 242 close(EASY_PM_IN); 243 244 print "Building Share.pm constants for your libcurl version\n"; 245 246 open(SHARE_PM, ">lib/WWW/Curl/Share.pm") or die "Can't create lib/WWW/Curl/Share.pm\n"; 247 open(SHARE_PM_IN, "template/Share.pm.tmpl") or die "Can't read template/Share.pm.tmpl\n"; 248 while (my $line = <SHARE_PM_IN>) { 249 if ($line !~ m/^(.*?)\@CURLSHOPT_INCLUDE\@/) { 250 print SHARE_PM $line; 251 } else { 252 foreach my $option (sort keys %{$constants{CURLSHOPT_}}) { 253 print SHARE_PM $1 . $option . "\n"; 254 } 255 foreach my $option (sort keys %{$constants{CURL_LOCK_}}) { 256 print SHARE_PM $1 . $option . "\n"; 257 } 258 } 259 } 260 close(SHARE_PM); 261 close(SHARE_PM_IN); 262} 263 264# Let Module::Install generate META.yml and other necessary files. 265WriteMakefile( 266 'NAME' => 'WWW::Curl', 267 'VERSION_FROM' => 'lib/WWW/Curl.pm', # finds $VERSION 268 'LIBS' => "$ldflags $lflags", # e.g., '-lm' 269 'INC' => $curl_d, # e.g., '-I/usr/include/other' 270 'clean' => { FILES => "curlopt-constants.c head.out body.out" } 271); 272 273