]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - make/configure.pm
Automatically detect the compiler which the user has installed.
[user/henk/code/inspircd.git] / make / configure.pm
1 #
2 # InspIRCd -- Internet Relay Chat Daemon
3 #
4 #   Copyright (C) 2012 Peter Powell <petpow@saberuk.com>
5 #   Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
6 #   Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
7 #   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
8 #   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
9 #
10 # This file is part of InspIRCd.  InspIRCd is free software: you can
11 # redistribute it and/or modify it under the terms of the GNU General Public
12 # License as published by the Free Software Foundation, version 2.
13 #
14 # This program is distributed in the hope that it will be useful, but WITHOUT
15 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17 # details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 #
22
23
24 package make::configure;
25
26 require 5.8.0;
27
28 use strict;
29 use warnings FATAL => qw(all);
30
31 use Exporter 'import';
32 use POSIX;
33 use make::utilities;
34 our @EXPORT = qw(find_compiler test_file test_header promptnumeric dumphash is_dir getmodules getrevision getcompilerflags getlinkerflags getdependencies nopedantic resolve_directory yesno showhelp promptstring_s module_installed);
35
36 my $no_git = 0;
37
38 sub find_compiler {
39         foreach my $compiler ('c++', 'g++', 'clang++', 'icpc') {
40                 return $compiler unless system "$compiler -v > /dev/null 2>&1";
41                 if ($^O eq 'Darwin') {
42                         return $compiler unless system "xcrun $compiler -v > /dev/null 2>&1";
43                 }
44         }
45         return "";
46 }
47
48 sub test_file($$;$) {
49         my ($cc, $file, $args) = @_;
50         my $status = 0;
51         $args ||= '';
52         $status ||= system "$cc -o __test_$file make/test/$file $args >/dev/null 2>&1";
53         $status ||= system "./__test_$file >/dev/null 2>&1";
54         unlink  "./__test_$file";
55         return !$status;
56 }
57
58 sub test_header($$;$) {
59         my ($cc, $header, $args) = @_;
60         $args ||= '';
61         open(CC, "| $cc -E - $args >/dev/null 2>&1") or return 0;
62         print CC "#include <$header>";
63         close(CC);
64         return !$?;
65 }
66
67 sub yesno {
68         my ($flag,$prompt) = @_;
69         print "$prompt [\e[1;32m$main::config{$flag}\e[0m] -> ";
70         chomp(my $tmp = <STDIN>);
71         if ($tmp eq "") { $tmp = $main::config{$flag} }
72         if (($tmp eq "") || ($tmp =~ /^y/i))
73         {
74                 $main::config{$flag} = "y";
75         }
76         else
77         {
78                 $main::config{$flag} = "n";
79         }
80         return;
81 }
82
83 sub resolve_directory
84 {
85         my $ret = $_[0];
86         eval
87         {
88                 use File::Spec;
89                 $ret = File::Spec->rel2abs($_[0]);
90         };
91         return $ret;
92 }
93
94 sub getrevision {
95         if ($no_git)
96         {
97                 return "0";
98         }
99         my $data = `git describe --tags 2>/dev/null`;
100         if ($data eq "")
101         {
102                 $no_git = 1;
103                 return '0';
104         }
105         chomp $data; # remove \n
106         return $data;
107 }
108
109 sub getcompilerflags {
110         my ($file) = @_;
111         open(FLAGS, $file) or return "";
112         while (<FLAGS>) {
113                 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
114                         my $x = translate_functions($1, $file);
115                         next if ($x eq "");
116                         close(FLAGS);
117                         return $x;
118                 }
119         }
120         close(FLAGS);
121         return "";
122 }
123
124 sub getlinkerflags {
125         my ($file) = @_;
126         open(FLAGS, $file) or return "";
127         while (<FLAGS>) {
128                 if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) {
129                         my $x = translate_functions($1, $file);
130                         next if ($x eq "");
131                         close(FLAGS);
132                         return $x;
133                 }
134         }
135         close(FLAGS);
136         return "";
137 }
138
139 sub getdependencies {
140         my ($file) = @_;
141         open(FLAGS, $file) or return "";
142         while (<FLAGS>) {
143                 if ($_ =~ /^\/\* \$ModDep: (.+) \*\/$/) {
144                         my $x = translate_functions($1, $file);
145                         next if ($x eq "");
146                         close(FLAGS);
147                         return $x;
148                 }
149         }
150         close(FLAGS);
151         return "";
152 }
153
154 sub nopedantic {
155         my ($file) = @_;
156         open(FLAGS, $file) or return "";
157         while (<FLAGS>) {
158                 if ($_ =~ /^\/\* \$NoPedantic \*\/$/) {
159                         my $x = translate_functions($_, $file);
160                         next if ($x eq "");
161                         close(FLAGS);
162                         return 1;
163                 }
164         }
165         close(FLAGS);
166         return 0;
167 }
168
169 sub getmodules
170 {
171         my ($silent) = @_;
172
173         my $i = 0;
174
175         if (!$silent)
176         {
177                 print "Detecting modules ";
178         }
179
180         opendir(DIRHANDLE, "src/modules") or die("WTF, missing src/modules!");
181         foreach my $name (sort readdir(DIRHANDLE))
182         {
183                 if ($name =~ /^m_(.+)\.cpp$/)
184                 {
185                         my $mod = $1;
186                         $main::modlist[$i++] = $mod;
187                         if (!$silent)
188                         {
189                                 print ".";
190                         }
191                 }
192         }
193         closedir(DIRHANDLE);
194
195         if (!$silent)
196         {
197                 print "\nOk, $i modules.\n";
198         }
199 }
200
201 sub promptnumeric($$)
202 {
203         my $continue = 0;
204         my ($prompt, $configitem) = @_;
205         while (!$continue)
206         {
207                 print "Please enter the maximum $prompt?\n";
208                 print "[\e[1;32m$main::config{$configitem}\e[0m] -> ";
209                 chomp(my $var = <STDIN>);
210                 if ($var eq "")
211                 {
212                         $var = $main::config{$configitem};
213                 }
214                 if ($var =~ /^\d+$/) {
215                         # We don't care what the number is, set it and be on our way.
216                         $main::config{$configitem} = $var;
217                         $continue = 1;
218                         print "\n";
219                 } else {
220                         print "You must enter a number in this field. Please try again.\n\n";
221                 }
222         }
223 }
224
225 sub module_installed($)
226 {
227         my $module = shift;
228         eval("use $module;");
229         return !$@;
230 }
231
232 sub promptstring_s($$)
233 {
234         my ($prompt,$default) = @_;
235         my $var;
236         print "$prompt\n";
237         print "[\e[1;32m$default\e[0m] -> ";
238         chomp($var = <STDIN>);
239         $var = $default if $var eq "";
240         print "\n";
241         return $var;
242 }
243
244 sub dumphash()
245 {
246         print "\n\e[1;32mPre-build configuration is complete!\e[0m\n\n";
247         print "\e[0mBase install path:\e[1;32m\t\t$main::config{BASE_DIR}\e[0m\n";
248         print "\e[0mConfig path:\e[1;32m\t\t\t$main::config{CONFIG_DIR}\e[0m\n";
249         print "\e[0mModule path:\e[1;32m\t\t\t$main::config{MODULE_DIR}\e[0m\n";
250         print "\e[0mGCC Version Found:\e[1;32m\t\t$main::config{GCCVER}.$main::config{GCCMINOR}\e[0m\n";
251         print "\e[0mCompiler program:\e[1;32m\t\t$main::config{CC}\e[0m\n";
252         print "\e[0mGnuTLS Support:\e[1;32m\t\t\t$main::config{USE_GNUTLS}\e[0m\n";
253         print "\e[0mOpenSSL Support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n\n";
254         print "\e[1;32mImportant note: The maximum length values are now configured in the\e[0m\n";
255         print "\e[1;32m                configuration file, not in ./configure! See the <limits>\e[0m\n";
256         print "\e[1;32m                tag in the configuration file for more information.\e[0m\n\n";
257 }
258
259 sub is_dir
260 {
261         my ($path) = @_;
262         if (chdir($path))
263         {
264                 chdir($main::this);
265                 return 1;
266         }
267         else
268         {
269                 # Just in case..
270                 chdir($main::this);
271                 return 0;
272         }
273 }
274
275 sub showhelp
276 {
277         chomp(my $PWD = `pwd`);
278         print <<EOH;
279 Usage: configure [options]
280
281 *** NOTE: NON-INTERACTIVE CONFIGURE IS *NOT* SUPPORTED BY THE ***
282 *** INSPIRCD DEVELOPMENT TEAM. DO NOT ASK FOR HELP REGARDING  ***
283 ***     NON-INTERACTIVE CONFIGURE ON THE FORUMS OR ON IRC!    ***
284
285 Options: [defaults in brackets after descriptions]
286
287 When no options are specified, interactive
288 configuration is started and you must specify
289 any required values manually. If one or more
290 options are specified, non-interactive configuration
291 is started, and any omitted values are defaulted.
292
293 Arguments with a single \"-\" symbol, as in
294 InspIRCd 1.0.x, are also allowed.
295
296   --disable-interactive        Sets no options itself, but
297                                will disable any interactive prompting.
298   --update                     Update makefiles and dependencies
299   --clean                      Remove .config.cache file and go interactive
300   --enable-gnutls              Enable GnuTLS module [no]
301   --enable-openssl             Enable OpenSSL module [no]
302   --enable-epoll               Enable epoll() where supported [set]
303   --enable-kqueue              Enable kqueue() where supported [set]
304   --disable-epoll              Do not enable epoll(), fall back
305                                to select() [not set]
306   --disable-kqueue             Do not enable kqueue(), fall back
307                                to select() [not set]
308   --prefix=[directory]         Base directory to install into (if defined,
309                                can automatically define config, module, bin
310                                and library dirs as subdirectories of prefix)
311                                [$PWD]
312   --config-dir=[directory]     Config file directory for config and SSL certs
313                                [$PWD/conf]
314   --log-dir=[directory]        Log file directory for logs
315                                [$PWD/logs]
316   --data-dir=[directory]       Data directory for variable data, such as the permchannel configuration and the XLine database
317                                [$PWD/data]
318   --module-dir=[directory]     Modules directory for loadable modules
319                                [$PWD/modules]
320   --binary-dir=[directory]     Binaries directory for core binary
321                                [$PWD/bin]
322   --library-dir=[directory]    Library directory for core libraries
323                                [$PWD/lib]
324   --list-extras                Show current status of extra modules
325   --enable-extras=[extras]     Enable the specified list of extras
326   --disable-extras=[extras]    Disable the specified list of extras
327   --help                       Show this help text and exit
328
329 EOH
330         exit(0);
331 }
332
333 1;
334