]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - make/utilities.pm
Remove references to SVN from the Makefile
[user/henk/code/inspircd.git] / make / utilities.pm
1 #       +------------------------------------+
2 #       | Inspire Internet Relay Chat Daemon |
3 #       +------------------------------------+
4 #
5 #  InspIRCd: (C) 2002-2010 InspIRCd Development Team
6 # See: http://wiki.inspircd.org/Credits
7 #
8 # This program is free but copyrighted software; see
9 #      the file COPYING for details.
10 #
11 # ---------------------------------------------------
12
13 package make::utilities;
14
15 require 5.8.0;
16
17 use strict;
18 use warnings FATAL => qw(all);
19
20 use Exporter 'import';
21 use POSIX;
22 use Getopt::Long;
23 use Fcntl;
24 our @EXPORT = qw(make_rpath pkgconfig_get_include_dirs pkgconfig_get_lib_dirs pkgconfig_check_version translate_functions promptstring);
25
26 # Parse the output of a *_config program,
27 # such as pcre_config, take out the -L
28 # directive and return an rpath for it.
29
30 # \e[1;32msrc/Makefile\e[0m
31
32 my %already_added = ();
33 my $if_skip_lines = 0;
34
35 sub promptstring($$$$$)
36 {
37         my ($prompt, $configitem, $default, $package, $commandlineswitch) = @_;
38         my $var;
39         if (!$main::interactive)
40         {
41                 my $opt_commandlineswitch;
42                 GetOptions ("$commandlineswitch=s" => \$opt_commandlineswitch);
43                 if (defined $opt_commandlineswitch)
44                 {
45                         print "\e[1;32m$opt_commandlineswitch\e[0m\n";
46                         $var = $opt_commandlineswitch;
47                 }
48                 else
49                 {
50                         die "Could not detect $package! Please specify the $prompt via the command line option \e[1;32m--$commandlineswitch=\"/path/to/file\"\e[0m";
51                 }
52         }
53         else
54         {
55                 print "\nPlease enter the $prompt?\n";
56                 print "[\e[1;32m$default\e[0m] -> ";
57                 chomp($var = <STDIN>);
58         }
59         if ($var eq "")
60         {
61                 $var = $default;
62         }
63         $main::config{$configitem} = $var;
64 }
65
66 sub make_rpath($;$)
67 {
68         my ($executable, $module) = @_;
69         chomp(my $data = `$executable`);
70         my $output = "";
71         while ($data =~ /-L(\S+)/)
72         {
73                 my $libpath = $1;
74                 if (!exists $already_added{$libpath})
75                 {
76                         print "Adding extra library path to \e[1;32m$module\e[0m ... \e[1;32m$libpath\e[0m\n";
77                         $already_added{$libpath} = 1;
78                 }
79                 $output .= "-Wl,--rpath -Wl,$libpath -L$libpath " unless defined $main::opt_disablerpath;
80                 $data =~ s/-L(\S+)//;
81         }
82         return $output;
83 }
84
85 sub extend_pkg_path()
86 {
87         if (!exists $ENV{PKG_CONFIG_PATH})
88         {
89                 $ENV{PKG_CONFIG_PATH} = "/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
90         }
91         else
92         {
93                 $ENV{PKG_CONFIG_PATH} .= ":/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
94         }
95 }
96
97 sub pkgconfig_get_include_dirs($$$;$)
98 {
99         my ($packagename, $headername, $defaults, $module) = @_;
100
101         my $key = "default_includedir_$packagename";
102         if (exists $main::config{$key})
103         {
104                 print "Locating include directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
105                 my $ret = $main::config{$key};
106                 print "\e[1;32m$ret\e[0m (cached)\n";
107                 return $ret;
108         }
109
110         extend_pkg_path();
111
112         print "Locating include directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
113
114         my $v = `pkg-config --modversion $packagename 2>/dev/null`;
115         my $ret = `pkg-config --cflags $packagename 2>/dev/null`;
116         my $foo = "";
117         if ((!defined $v) || ($v eq ""))
118         {
119                 print "\e[31mCould not find $packagename via pkg-config\e[m (\e[1;32mplease install pkg-config\e[m)\n";
120                 $foo = `locate "$headername" 2>/dev/null | head -n 1`;
121                 my $find = $foo =~ /(.+)\Q$headername\E/ ? $1 : '';
122                 chomp($find);
123                 if ((defined $find) && ($find ne "") && ($find ne $packagename))
124                 {
125                         print "(\e[1;32mFound via search\e[0m) ";
126                         $foo = "-I$1";
127                 }
128                 else
129                 {
130                         $foo = " ";
131                         undef $v;
132                 }
133                 $ret = "$foo";
134         }
135         if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
136         {
137                 $ret = "$foo " . $defaults;
138         }
139         chomp($ret);
140         if ((($ret eq " ") || (!defined $ret)) && ((!defined $v) || ($v eq "")))
141         {
142                 my $key = "default_includedir_$packagename";
143                 if (exists $main::config{$key})
144                 {
145                         $ret = $main::config{$key};
146                 }
147                 else
148                 {
149                         $headername =~ s/^\///;
150                         promptstring("path to the directory containing $headername", $key, "/usr/include",$packagename,"$packagename-includes");
151                         $packagename =~ tr/a-z/A-Z/;
152                         if (defined $v)
153                         {
154                                 $main::config{$key} = "-I$main::config{$key}" . " $defaults -DVERSION_$packagename=\"$v\"";
155                         }
156                         else
157                         {
158                                 $main::config{$key} = "-I$main::config{$key}" . " $defaults -DVERSION_$packagename=\"0.0\"";
159                         }
160                         $main::config{$key} =~ s/^\s+//g;
161                         $ret = $main::config{$key};
162                         return $ret;
163                 }
164         }
165         else
166         {
167                 chomp($v);
168                 my $key = "default_includedir_$packagename";
169                 $packagename =~ tr/a-z/A-Z/;
170                 $main::config{$key} = "$ret -DVERSION_$packagename=\"$v\"";
171                 $main::config{$key} =~ s/^\s+//g;
172                 $ret = $main::config{$key};
173                 print "\e[1;32m$ret\e[0m (version $v)\n";
174         }
175         $ret =~ s/^\s+//g;
176         return $ret;
177 }
178
179 sub pkgconfig_check_version($$;$)
180 {
181         my ($packagename, $version, $module) = @_;
182
183         extend_pkg_path();
184
185         print "Checking version of package \e[1;32m$packagename\e[0m is >= \e[1;32m$version\e[0m... ";
186
187         my $v = `pkg-config --modversion $packagename 2>/dev/null`;
188         if (defined $v)
189         {
190                 chomp($v);
191         }
192         if ((defined $v) && ($v ne ""))
193         {
194                 if (!system "pkg-config --atleast-version $version $packagename")
195                 {
196                         print "\e[1;32mYes (version $v)\e[0m\n";
197                         return 1;
198                 }
199                 else
200                 {
201                         print "\e[1;32mNo (version $v)\e[0m\n";
202                         return 0;
203                 }
204         }
205         # If we didnt find it, we  cant definitively say its too old.
206         # Return ok, and let pkgconflibs() or pkgconfincludes() pick up
207         # the missing library later on.
208         print "\e[1;32mNo (not found)\e[0m\n";
209         return 1;
210 }
211
212 sub pkgconfig_get_lib_dirs($$$;$)
213 {
214         my ($packagename, $libname, $defaults, $module) = @_;
215
216         my $key = "default_libdir_$packagename";
217         if (exists $main::config{$key})
218         {
219                 print "Locating library directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
220                 my $ret = $main::config{$key};
221                 print "\e[1;32m$ret\e[0m (cached)\n";
222                 return $ret;
223         }
224
225         extend_pkg_path();
226
227         print "Locating library directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
228
229         my $v = `pkg-config --modversion $packagename 2>/dev/null`;
230         my $ret = `pkg-config --libs $packagename 2>/dev/null`;
231
232         my $foo = "";
233         if ((!defined $v) || ($v eq ""))
234         {
235                 $foo = `locate "$libname" | head -n 1`;
236                 $foo =~ /(.+)\Q$libname\E/;
237                 my $find = $1;
238                 chomp($find);
239                 if ((defined $find) && ($find ne "") && ($find ne $packagename))
240                 {
241                         print "(\e[1;32mFound via search\e[0m) ";
242                         $foo = "-L$1";
243                 }
244                 else
245                 {
246                         $foo = " ";
247                         undef $v;
248                 }
249                 $ret = "$foo";
250         }
251
252         if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
253         {
254                 $ret = "$foo " . $defaults;
255         }
256         chomp($ret);
257         if ((($ret eq " ") || (!defined $ret)) && ((!defined $v) || ($v eq "")))
258         {
259                 my $key = "default_libdir_$packagename";
260                 if (exists $main::config{$key})
261                 {
262                         $ret = $main::config{$key};
263                 }
264                 else
265                 {
266                         $libname =~ s/^\///;
267                         promptstring("path to the directory containing $libname", $key, "/usr/lib",$packagename,"$packagename-libs");
268                         $main::config{$key} = "-L$main::config{$key}" . " $defaults";
269                         $main::config{$key} =~ s/^\s+//g;
270                         $ret = $main::config{$key};
271                         return $ret;
272                 }
273         }
274         else
275         {
276                 chomp($v);
277                 print "\e[1;32m$ret\e[0m (version $v)\n";
278                 my $key = "default_libdir_$packagename";
279                 $main::config{$key} = $ret;
280                 $main::config{$key} =~ s/^\s+//g;
281                 $ret =~ s/^\s+//g;
282         }
283         $ret =~ s/^\s+//g;
284         return $ret;
285 }
286
287 # Translate a $CompileFlags etc line and parse out function calls
288 # to functions within these modules at configure time.
289 sub translate_functions($$)
290 {
291         my ($line,$module) = @_;
292
293         eval
294         {
295                 $module =~ /modules*\/(.+?)$/;
296                 $module = $1;
297
298                 # This is only a cursory check, just designed to catch casual accidental use of backticks.
299                 # There are pleanty of ways around it, but its not supposed to be for security, just checking
300                 # that people are using the new configuration api as theyre supposed to and not just using
301                 # backticks instead of eval(), being as eval has accountability. People wanting to get around
302                 # the accountability will do so anyway.
303                 if (($line =~ /`/) && ($line !~ /eval\(.+?`.+?\)/))
304                 {
305                         die "Developers should no longer use backticks in configuration macros. Please use exec() and eval() macros instead. Offending line: $line (In module: $module)";
306                 }
307
308                 if ($line =~ /ifuname\(\!"(\w+)"\)/)
309                 {
310                         my $uname = $1;
311                         if ($uname eq $^O)
312                         {
313                                 $line = "";
314                                 return "";
315                         }
316
317                         $line =~ s/ifuname\(\!"(.+?)"\)//;
318                 }
319
320                 if ($line =~ /ifuname\("(\w+)"\)/)
321                 {
322                         my $uname = $1;
323                         if ($uname ne $^O)
324                         {
325                                 $line = "";
326                                 return "";
327                         }
328
329                         $line =~ s/ifuname\("(.+?)"\)//;
330                 }
331
332                 if ($line =~ /if\("(\w+)"\)/)
333                 {
334                         if (defined $main::config{$1})
335                         {
336                                 if (($main::config{$1} !~ /y/i) and ($main::config{$1} ne "1"))
337                                 {
338                                         $line = "";
339                                         return "";
340                                 }
341                         }
342
343                         $line =~ s/if\("(.+?)"\)//;
344                 }
345                 if ($line =~ /if\(\!"(\w+)"\)/)
346                 {
347                         if (!exists $main::config{$1})
348                         {
349                                 $line = "";
350                                 return "";
351                         }
352                         else
353                         {
354                                 if (defined $1)
355                                 {
356                                         if (exists ($main::config{$1}) and (($main::config{$1} =~ /y/i) or ($main::config{$1} eq "1")))
357                                         {
358                                                 $line = "";
359                                                 return "";
360                                         }
361                                 }
362                         }
363
364                         $line =~ s/if\(\!"(.+?)"\)//;
365                 }
366                 while ($line =~ /exec\("(.+?)"\)/)
367                 {
368                         print "Executing program for module \e[1;32m$module\e[0m ... \e[1;32m$1\e[0m\n";
369                         my $replace = `$1`;
370                         die $replace if ($replace =~ /Configuration failed/);
371                         chomp($replace);
372                         $line =~ s/exec\("(.+?)"\)/$replace/;
373                 }
374                 while ($line =~ /execruntime\("(.+?)"\)/)
375                 {
376                         $line =~ s/execruntime\("(.+?)"\)/`$1`/;
377                 }
378                 while ($line =~ /eval\("(.+?)"\)/)
379                 {
380                         print "Evaluating perl code for module \e[1;32m$module\e[0m ... ";
381                         my $tmpfile;
382                         do
383                         {
384                                 $tmpfile = tmpnam();
385                         } until sysopen(TF, $tmpfile, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0700);
386                         print "(Created and executed \e[1;32m$tmpfile\e[0m)\n";
387                         print TF $1;
388                         close TF;
389                         my $replace = `perl $tmpfile`;
390                         chomp($replace);
391                         $line =~ s/eval\("(.+?)"\)/$replace/;
392                 }
393                 while ($line =~ /pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/)
394                 {
395                         my $replace = pkgconfig_get_lib_dirs($1, $2, $3, $module);
396                         $line =~ s/pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/$replace/;
397                 }
398                 while ($line =~ /pkgconfversion\("(.+?)","(.+?)"\)/)
399                 {
400                         if (pkgconfig_check_version($1, $2, $module) != 1)
401                         {
402                                 die "Version of package $1 is too old. Please upgrade it to version \e[1;32m$2\e[0m or greater and try again.";
403                         }
404                         # This doesnt actually get replaced with anything
405                         $line =~ s/pkgconfversion\("(.+?)","(.+?)"\)//;
406                 }
407                 while ($line =~ /pkgconflibs\("(.+?)","(.+?)",""\)/)
408                 {
409                         my $replace = pkgconfig_get_lib_dirs($1, $2, "", $module);
410                         $line =~ s/pkgconflibs\("(.+?)","(.+?)",""\)/$replace/;
411                 }
412                 while ($line =~ /pkgconfincludes\("(.+?)","(.+?)",""\)/)
413                 {
414                         my $replace = pkgconfig_get_include_dirs($1, $2, "", $module);
415                         $line =~ s/pkgconfincludes\("(.+?)","(.+?)",""\)/$replace/;
416                 }
417                 while ($line =~ /pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/)
418                 {
419                         my $replace = pkgconfig_get_include_dirs($1, $2, $3, $module);
420                         $line =~ s/pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/$replace/;
421                 }
422                 while ($line =~ /rpath\("(.+?)"\)/)
423                 {
424                         my $replace = make_rpath($1,$module);
425                         $replace = "" if ($^O =~ /darwin/i);
426                         $line =~ s/rpath\("(.+?)"\)/$replace/;
427                 }
428         };
429         if ($@)
430         {
431                 my $err = $@;
432                 #$err =~ s/at .+? line \d+.*//g;
433                 print "\n\nConfiguration failed. The following error occured:\n\n$err\n";
434                 print "\nMake sure you have pkg-config installed\n";
435                 print "\nIn the case of gnutls configuration errors on debian,\n";
436                 print "Ubuntu, etc, you should ensure that you have installed\n";
437                 print "gnutls-bin as well as gnutls-dev and gnutls.\n";
438                 exit;
439         }
440         else
441         {
442                 return $line;
443         }
444 }
445
446 1;
447