]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - make/utilities.pm
982337577c59fbf4a81a96b8cdf779170064087c
[user/henk/code/inspircd.git] / make / utilities.pm
1 package make::utilities;
2 use Exporter 'import';
3 use make::configure;
4 use POSIX;
5 @EXPORT = qw(make_rpath pkgconfig_get_include_dirs pkgconfig_get_lib_dirs translate_functions);
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 make_rpath($;$)
16 {
17         my ($executable, $module) = @_;
18         chomp($data = `$executable`);
19         my $output = "";
20         while ($data =~ /-L(\S+)/)
21         {
22                 $libpath = $1;
23                 if (!exists $already_added{$libpath})
24                 {
25                         print "Adding extra library path to \033[1;32m$module\033[0m ... \033[1;32m$libpath\033[0m\n";
26                         $already_added{$libpath} = 1;
27                 }
28                 $output .= "-Wl,--rpath -Wl,$libpath -L$libpath ";
29                 $data =~ s/-L(\S+)//;
30         }
31         return $output;
32 }
33
34 sub extend_pkg_path()
35 {
36         if (!exists $ENV{PKG_CONFIG_PATH})
37         {
38                 $ENV{PKG_CONFIG_PATH} = "/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
39         }
40         else
41         {
42                 $ENV{PKG_CONFIG_PATH} .= ":/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
43         }
44 }
45
46 sub pkgconfig_get_include_dirs($$$;$)
47 {
48         my ($packagename, $headername, $defaults, $module) = @_;
49
50         if (exists $config{$key})
51         {
52                 my $key = "default_includedir_$packagename";
53                 $ret = $config{$key};
54                 return $ret;
55         }
56
57         extend_pkg_path();
58
59         print "Locating include directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... ";
60
61         $ret = `pkg-config --cflags $packagename 2>/dev/null`;
62         if ((!defined $ret) || ($ret eq ""))
63         {
64                 $foo = `locate "$headername" | head -n 1`;
65                 $foo =~ /(.+)\Q$headername\E/;
66                 if (defined $1)
67                 {
68                         $foo = "-I$1";
69                 }
70                 else
71                 {
72                         $foo = "";
73                 }
74                 $ret = "$foo";
75         }
76         if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
77         {
78                 $ret = "$foo " . $defaults;
79         }
80         chomp($ret);
81         if (($ret eq " ") || (!defined $ret))
82         {
83                 my $key = "default_includedir_$packagename";
84                 if (exists $config{$key})
85                 {
86                         $ret = $config{$key};
87                 }
88                 else
89                 {
90                         $headername =~ s/^\///;
91                         promptstring("path to the directory containing $headername", $key, "/usr/include");
92                         $ret = $config{$key};
93                 }
94         }
95         else
96         {
97                 print "\033[1;32m$ret\033[0m\n";
98         }
99         return $ret;
100 }
101
102 sub pkgconfig_get_lib_dirs($$$;$)
103 {
104         my ($packagename, $libname, $defaults, $module) = @_;
105
106         if (exists $config{$key})
107         {
108                 my $key = "default_libdir_$packagename";
109                 $ret = $config{$key};
110                 return $ret;
111         }
112
113         extend_pkg_path();
114
115         print "Locating library directory for package \033[1;32m$packagename\033[0m for module \033[1;32m$module\033[0m... ";
116
117         $ret = `pkg-config --libs $packagename 2>/dev/null`;
118         if ((!defined $ret) || ($ret eq ""))
119         {
120                 $foo = `locate "$libname" | head -n 1`;
121                 $foo =~ /(.+)\Q$libname\E/;
122                 if (defined $1)
123                 {
124                         $foo = "-L$1";
125                 }
126                 else
127                 {
128                         $foo = "";
129                 }
130                 $ret = "$foo";
131         }
132
133         if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
134         {
135                 $ret = "$foo " . $defaults;
136         }
137         chomp($ret);
138         if (($ret eq " ") || (!defined $ret))
139         {
140                 my $key = "default_libdir_$packagename";
141                 if (exists $config{$key})
142                 {
143                         $ret = $config{$key};
144                 }
145                 else
146                 {
147                         $libname =~ s/^\///;
148                         promptstring("path to the directory containing $libname", $key, "/usr/lib");
149                         $ret = $config{$key};
150                 }
151         }
152         else
153         {
154                 print "\033[1;32m$ret\033[0m\n";
155         }
156         return $ret;
157 }
158
159 # Translate a $CompileFlags etc line and parse out function calls
160 # to functions within these modules at configure time.
161 sub translate_functions($$)
162 {
163         my ($line,$module) = @_;
164
165         eval
166         {
167                 $module =~ /modules*\/(.+?)$/;
168                 $module = $1;
169
170                 # This is only a cursory check, just designed to catch casual accidental use of backticks.
171                 # There are pleanty of ways around it, but its not supposed to be for security, just checking
172                 # that people are using the new configuration api as theyre supposed to and not just using
173                 # backticks instead of eval(), being as eval has accountability. People wanting to get around
174                 # the accountability will do so anyway.
175                 if (($line =~ /`/) && ($line !~ /eval\(.+?`.+?\)/))
176                 {
177                         die "Developers should no longer use backticks in configuration macros. Please use exec() and eval() macros instead. Offending line: $line (In module: $module)";
178                 }
179                 while ($line =~ /exec\("(.+?)"\)/)
180                 {
181                         print "Executing program for module \033[1;32m$module\033[0m ... \033[1;32m$1\033[0m\n";
182                         my $replace = `$1`;
183                         chomp($replace);
184                         $line =~ s/exec\("(.+?)"\)/$replace/;
185                 }
186                 while ($line =~ /eval\("(.+?)"\)/)
187                 {
188                         print "Evaluating perl code for module \033[1;32m$module\033[0m ... ";
189                         my $tmpfile;
190                         do
191                         {
192                                 $tmpfile = tmpnam();
193                         } until sysopen(TF, $tmpfile, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0700);
194                         print "(Created and executed \033[1;32m$tmpfile\033[0m)\n";
195                         print TF $1;
196                         close TF;
197                         my $replace = `perl $tmpfile`;
198                         chomp($replace);
199                         $line =~ s/eval\("(.+?)"\)/$replace/;
200                 }
201                 while ($line =~ /pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/)
202                 {
203                         my $replace = pkgconfig_get_lib_dirs($1, $2, $3, $module);
204                         $line =~ s/pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/$replace/;
205                 }
206                 while ($line =~ /pkgconflibs\("(.+?)","(.+?)",""\)/)
207                 {
208                         my $replace = pkgconfig_get_lib_dirs($1, $2, "", $module);
209                         $line =~ s/pkgconflibs\("(.+?)","(.+?)",""\)/$replace/;
210                 }
211                 while ($line =~ /pkgconfincludes\("(.+?)","(.+?)",""\)/)
212                 {
213                         my $replace = pkgconfig_get_include_dirs($1, $2, "", $module);
214                         $line =~ s/pkgconfincludes\("(.+?)","(.+?)",""\)/$replace/;
215                 }
216                 while ($line =~ /pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/)
217                 {
218                         my $replace = pkgconfig_get_include_dirs($1, $2, $3, $module);
219                         $line =~ s/pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/$replace/;
220                 }
221                 while ($line =~ /rpath\("(.+?)"\)/)
222                 {
223                         my $replace = make_rpath($1,$module);
224                         $line =~ s/rpath\("(.+?)"\)/$replace/;
225                 }
226         };
227         if ($@)
228         {
229                 print "\n\nConfiguration failed. The following error occured:\n\n$@\n";
230                 exit;
231         }
232         else
233         {
234                 return $line;
235         }
236 }
237
238 1;
239