]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - make/utilities.pm
2227200585308233381c81a8918111f132978757
[user/henk/code/inspircd.git] / make / utilities.pm
1 package make::utilities;
2 use Exporter 'import';
3 use POSIX;
4 use Getopt::Long;
5 @EXPORT = qw(make_rpath pkgconfig_get_include_dirs pkgconfig_get_lib_dirs translate_functions promptstring);
6
7 # Parse the output of a *_config program,
8 # such as pcre_config, take out the -L
9 # directive and return an rpath for it.
10
11 # \033[1;32msrc/Makefile\033[0m
12
13 my %already_added = ();
14
15 sub promptstring($$$$$)
16 {
17         my ($prompt, $configitem, $default, $package, $commandlineswitch) = @_;
18         my $var;
19         if (!$main::interactive)
20         {
21                 undef $opt_commandlineswitch;
22                 GetOptions ("$commandlineswitch" => \$opt_commandlineswitch);
23                 if (defined $opt_commandlineswitch)
24                 {
25                         $var = $opt_commandlineswitch;
26                 }
27                 else
28                 {
29                         die "Could not detect $package! Please specify the $prompt via the command line option $commandlineswitch=\"/path/to/file\"";
30                 }
31         }
32         else
33         {
34                 print "\nPlease enter the $prompt?\n";
35                 print "[\033[1;32m$default\033[0m] -> ";
36                 chomp($var = <STDIN>);
37         }
38         if ($var eq "")
39         {
40                 $var = $default;
41         }
42         $main::config{$configitem} = $var;
43 }
44
45 sub make_rpath($;$)
46 {
47         my ($executable, $module) = @_;
48         chomp($data = `$executable`);
49         my $output = "";
50         while ($data =~ /-L(\S+)/)
51         {
52                 $libpath = $1;
53                 if (!exists $already_added{$libpath})
54                 {
55                         print "Adding extra library path to \033[1;32m$module\033[0m ... \033[1;32m$libpath\033[0m\n";
56                         $already_added{$libpath} = 1;
57                 }
58                 $output .= "-Wl,--rpath -Wl,$libpath -L$libpath ";
59                 $data =~ s/-L(\S+)//;
60         }
61         return $output;
62 }
63
64 sub extend_pkg_path()
65 {
66         if (!exists $ENV{PKG_CONFIG_PATH})
67         {
68                 $ENV{PKG_CONFIG_PATH} = "/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
69         }
70         else
71         {
72                 $ENV{PKG_CONFIG_PATH} .= ":/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
73         }
74 }
75
76 sub pkgconfig_get_include_dirs($$$;$)
77 {
78         my ($packagename, $headername, $defaults, $module) = @_;
79
80         my $key = "default_includedir_$packagename";
81         if (exists $main::config{$key})
82         {
83                 print "Locating include directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... ";
84                 $ret = $main::config{$key};
85                 print "\033[1;32m$ret\033[0m (cached)\n";
86                 return $ret;
87         }
88
89         extend_pkg_path();
90
91         print "Locating include directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... ";
92
93         $v = `pkg-config --modversion $packagename 2>/dev/null`;
94         $ret = `pkg-config --cflags $packagename 2>/dev/null`;
95
96         if ((!defined $v) || ($v eq ""))
97         {
98                 $foo = `locate "$headername" | head -n 1`;
99                 $foo =~ /(.+)\Q$headername\E/;
100                 if (defined $1)
101                 {
102                         $foo = "-I$1";
103                 }
104                 else
105                 {
106                         $foo = "";
107                 }
108                 $ret = "$foo";
109         }
110         if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
111         {
112                 $ret = "$foo " . $defaults;
113         }
114         chomp($ret);
115         if ((($ret eq " ") || (!defined $ret)) && ((!defined $v) || ($v eq "")))
116         {
117                 my $key = "default_includedir_$packagename";
118                 if (exists $main::config{$key})
119                 {
120                         $ret = $main::config{$key};
121                 }
122                 else
123                 {
124                         $headername =~ s/^\///;
125                         promptstring("path to the directory containing $headername", $key, "/usr/include",$packagename,"$packagename-includes");
126                         $packagename =~ tr/a-z/A-Z/;
127                         $main::config{$key} = "-I$main::config{$key}" . " $defaults -DVERSION_$packagename=\"$v\"";
128                         $main::config{$key} =~ s/^\s+//g;
129                         $ret = $main::config{$key};
130                         return $ret;
131                 }
132         }
133         else
134         {
135                 chomp($v);
136                 my $key = "default_includedir_$packagename";
137                 $packagename =~ tr/a-z/A-Z/;
138                 $main::config{$key} = "$ret -DVERSION_$packagename=\"$v\"";
139                 $main::config{$key} =~ s/^\s+//g;
140                 $ret = $main::config{$key};
141                 print "\033[1;32m$ret\033[0m (version $v)\n";
142         }
143         $ret =~ s/^\s+//g;
144         return $ret;
145 }
146
147 sub pkgconfig_get_lib_dirs($$$;$)
148 {
149         my ($packagename, $libname, $defaults, $module) = @_;
150
151         my $key = "default_libdir_$packagename";
152         if (exists $main::config{$key})
153         {
154                 print "Locating library directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... ";
155                 $ret = $main::config{$key};
156                 print "\033[1;32m$ret\033[0m (cached)\n";
157                 return $ret;
158         }
159
160         extend_pkg_path();
161
162         print "Locating library directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... ";
163
164         $v = `pkg-config --modversion $packagename 2>/dev/null`;
165         $ret = `pkg-config --libs $packagename 2>/dev/null`;
166
167         if ((!defined $v) || ($v eq ""))
168         {
169                 $foo = `locate "$libname" | head -n 1`;
170                 $foo =~ /(.+)\Q$libname\E/;
171                 if (defined $1)
172                 {
173                         $foo = "-L$1";
174                 }
175                 else
176                 {
177                         $foo = "";
178                 }
179                 $ret = "$foo";
180         }
181
182         if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
183         {
184                 $ret = "$foo " . $defaults;
185         }
186         chomp($ret);
187         if ((($ret eq " ") || (!defined $ret)) && ((!defined $v) || ($v eq "")))
188         {
189                 my $key = "default_libdir_$packagename";
190                 if (exists $main::config{$key})
191                 {
192                         $ret = $main::config{$key};
193                 }
194                 else
195                 {
196                         $libname =~ s/^\///;
197                         promptstring("path to the directory containing $libname", $key, "/usr/lib",$packagename,"$packagename-libs");
198                         $main::config{$key} = "-L$main::config{$key}" . " $defaults";
199                         $main::config{$key} =~ s/^\s+//g;
200                         $ret = $main::config{$key};
201                         return $ret;
202                 }
203         }
204         else
205         {
206                 chomp($v);
207                 print "\033[1;32m$ret\033[0m (version $v)\n";
208                 my $key = "default_libdir_$packagename";
209                 $main::config{$key} = $ret;
210                 $main::config{$key} =~ s/^\s+//g;
211                 $ret =~ s/^\s+//g;
212         }
213         return "$ret -DVERSION_$libname=\"$v\"";
214 }
215
216 # Translate a $CompileFlags etc line and parse out function calls
217 # to functions within these modules at configure time.
218 sub translate_functions($$)
219 {
220         my ($line,$module) = @_;
221
222         eval
223         {
224                 $module =~ /modules*\/(.+?)$/;
225                 $module = $1;
226
227                 # This is only a cursory check, just designed to catch casual accidental use of backticks.
228                 # There are pleanty of ways around it, but its not supposed to be for security, just checking
229                 # that people are using the new configuration api as theyre supposed to and not just using
230                 # backticks instead of eval(), being as eval has accountability. People wanting to get around
231                 # the accountability will do so anyway.
232                 if (($line =~ /`/) && ($line !~ /eval\(.+?`.+?\)/))
233                 {
234                         die "Developers should no longer use backticks in configuration macros. Please use exec() and eval() macros instead. Offending line: $line (In module: $module)";
235                 }
236                 while ($line =~ /exec\("(.+?)"\)/)
237                 {
238                         print "Executing program for module \033[1;32m$module\033[0m ... \033[1;32m$1\033[0m\n";
239                         my $replace = `$1`;
240                         chomp($replace);
241                         $line =~ s/exec\("(.+?)"\)/$replace/;
242                 }
243                 while ($line =~ /eval\("(.+?)"\)/)
244                 {
245                         print "Evaluating perl code for module \033[1;32m$module\033[0m ... ";
246                         my $tmpfile;
247                         do
248                         {
249                                 $tmpfile = tmpnam();
250                         } until sysopen(TF, $tmpfile, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0700);
251                         print "(Created and executed \033[1;32m$tmpfile\033[0m)\n";
252                         print TF $1;
253                         close TF;
254                         my $replace = `perl $tmpfile`;
255                         chomp($replace);
256                         $line =~ s/eval\("(.+?)"\)/$replace/;
257                 }
258                 while ($line =~ /pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/)
259                 {
260                         my $replace = pkgconfig_get_lib_dirs($1, $2, $3, $module);
261                         $line =~ s/pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/$replace/;
262                 }
263                 while ($line =~ /pkgconflibs\("(.+?)","(.+?)",""\)/)
264                 {
265                         my $replace = pkgconfig_get_lib_dirs($1, $2, "", $module);
266                         $line =~ s/pkgconflibs\("(.+?)","(.+?)",""\)/$replace/;
267                 }
268                 while ($line =~ /pkgconfincludes\("(.+?)","(.+?)",""\)/)
269                 {
270                         my $replace = pkgconfig_get_include_dirs($1, $2, "", $module);
271                         $line =~ s/pkgconfincludes\("(.+?)","(.+?)",""\)/$replace/;
272                 }
273                 while ($line =~ /pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/)
274                 {
275                         my $replace = pkgconfig_get_include_dirs($1, $2, $3, $module);
276                         $line =~ s/pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/$replace/;
277                 }
278                 while ($line =~ /rpath\("(.+?)"\)/)
279                 {
280                         my $replace = make_rpath($1,$module);
281                         $line =~ s/rpath\("(.+?)"\)/$replace/;
282                 }
283         };
284         if ($@)
285         {
286                 print "\n\nConfiguration failed. The following error occured:\n\n$@\n";
287                 exit;
288         }
289         else
290         {
291                 return $line;
292         }
293 }
294
295 1;
296