]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - make/configure.pm
Merge pull request #590 from SaberUK/master+module-logging
[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(get_compiler_info find_compiler test_file test_header promptnumeric dumphash getmodules getrevision getcompilerflags getlinkerflags getdependencies nopedantic yesno showhelp promptstring_s module_installed);
35
36 my $revision;
37
38 sub get_compiler_info($) {
39         my %info = (NAME => shift, VERSION => '0.0');
40         my $version = `$info{NAME} -v 2>&1`;
41                 return (ERROR => 1) if $?;
42         if ($version =~ /(?:clang|llvm)\sversion\s(\d+\.\d+)/i) {
43                 $info{NAME} = 'Clang';
44                 $info{VERSION} = $1;
45                 $info{UNSUPPORTED} = $1 lt '3.0';
46                 $info{REASON} = 'Clang 2.9 and older do not have adequate C++ support.';
47         } elsif ($version =~ /gcc\sversion\s(\d+\.\d+)/i) {
48                 $info{NAME} = 'GCC';
49                 $info{VERSION} = $1;
50                 $info{UNSUPPORTED} = $1 lt '4.1';
51                 $info{REASON} = 'GCC 4.0 and older do not have adequate C++ support.';
52         } elsif ($version =~ /(?:icc|icpc)\sversion\s(\d+\.\d+).\d+\s\(gcc\sversion\s(\d+\.\d+).\d+/i) {
53                 $info{NAME} = 'ICC';
54                 $info{VERSION} = $1;
55                 $info{UNSUPPORTED} = $2 lt '4.1';
56                 $info{REASON} = "ICC $1 (GCC $2 compatibility mode) does not have adequate C++ support."
57         }
58         return %info;
59 }  
60
61 sub find_compiler {
62         foreach my $compiler ('c++', 'g++', 'clang++', 'icpc') {
63                 return $compiler unless system "$compiler -v > /dev/null 2>&1";
64                 if ($^O eq 'Darwin') {
65                         return $compiler unless system "xcrun $compiler -v > /dev/null 2>&1";
66                 }
67         }
68         return "";
69 }
70
71 sub test_file($$;$) {
72         my ($cc, $file, $args) = @_;
73         my $status = 0;
74         $args ||= '';
75         $status ||= system "$cc -o __test_$file make/test/$file $args >/dev/null 2>&1";
76         $status ||= system "./__test_$file >/dev/null 2>&1";
77         unlink  "./__test_$file";
78         return !$status;
79 }
80
81 sub test_header($$;$) {
82         my ($cc, $header, $args) = @_;
83         $args ||= '';
84         open(CC, "| $cc -E - $args >/dev/null 2>&1") or return 0;
85         print CC "#include <$header>";
86         close(CC);
87         return !$?;
88 }
89
90 sub yesno {
91         my ($flag,$prompt) = @_;
92         print "$prompt [\e[1;32m$main::config{$flag}\e[0m] -> ";
93         chomp(my $tmp = <STDIN>);
94         if ($tmp eq "") { $tmp = $main::config{$flag} }
95         if (($tmp eq "") || ($tmp =~ /^y/i))
96         {
97                 $main::config{$flag} = "y";
98         }
99         else
100         {
101                 $main::config{$flag} = "n";
102         }
103         return;
104 }
105
106 sub getrevision {
107         return $revision if defined $revision;
108         chomp(my $tags = `git describe --tags 2>/dev/null`);
109         $revision = $tags || 'release';
110         return $revision;
111 }
112
113 sub getcompilerflags {
114         my ($file) = @_;
115         open(FLAGS, $file) or return "";
116         while (<FLAGS>) {
117                 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
118                         my $x = translate_functions($1, $file);
119                         next if ($x eq "");
120                         close(FLAGS);
121                         return $x;
122                 }
123         }
124         close(FLAGS);
125         return "";
126 }
127
128 sub getlinkerflags {
129         my ($file) = @_;
130         open(FLAGS, $file) or return "";
131         while (<FLAGS>) {
132                 if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) {
133                         my $x = translate_functions($1, $file);
134                         next if ($x eq "");
135                         close(FLAGS);
136                         return $x;
137                 }
138         }
139         close(FLAGS);
140         return "";
141 }
142
143 sub getdependencies {
144         my ($file) = @_;
145         open(FLAGS, $file) or return "";
146         while (<FLAGS>) {
147                 if ($_ =~ /^\/\* \$ModDep: (.+) \*\/$/) {
148                         my $x = translate_functions($1, $file);
149                         next if ($x eq "");
150                         close(FLAGS);
151                         return $x;
152                 }
153         }
154         close(FLAGS);
155         return "";
156 }
157
158 sub nopedantic {
159         my ($file) = @_;
160         open(FLAGS, $file) or return "";
161         while (<FLAGS>) {
162                 if ($_ =~ /^\/\* \$NoPedantic \*\/$/) {
163                         my $x = translate_functions($_, $file);
164                         next if ($x eq "");
165                         close(FLAGS);
166                         return 1;
167                 }
168         }
169         close(FLAGS);
170         return 0;
171 }
172
173 sub getmodules
174 {
175         my ($silent) = @_;
176
177         my $i = 0;
178
179         if (!$silent)
180         {
181                 print "Detecting modules ";
182         }
183
184         opendir(DIRHANDLE, "src/modules") or die("WTF, missing src/modules!");
185         foreach my $name (sort readdir(DIRHANDLE))
186         {
187                 if ($name =~ /^m_(.+)\.cpp$/)
188                 {
189                         my $mod = $1;
190                         $main::modlist[$i++] = $mod;
191                         if (!$silent)
192                         {
193                                 print ".";
194                         }
195                 }
196         }
197         closedir(DIRHANDLE);
198
199         if (!$silent)
200         {
201                 print "\nOk, $i modules.\n";
202         }
203 }
204
205 sub promptnumeric($$)
206 {
207         my $continue = 0;
208         my ($prompt, $configitem) = @_;
209         while (!$continue)
210         {
211                 print "Please enter the maximum $prompt?\n";
212                 print "[\e[1;32m$main::config{$configitem}\e[0m] -> ";
213                 chomp(my $var = <STDIN>);
214                 if ($var eq "")
215                 {
216                         $var = $main::config{$configitem};
217                 }
218                 if ($var =~ /^\d+$/) {
219                         # We don't care what the number is, set it and be on our way.
220                         $main::config{$configitem} = $var;
221                         $continue = 1;
222                         print "\n";
223                 } else {
224                         print "You must enter a number in this field. Please try again.\n\n";
225                 }
226         }
227 }
228
229 sub module_installed($)
230 {
231         my $module = shift;
232         eval("use $module;");
233         return !$@;
234 }
235
236 sub promptstring_s($$)
237 {
238         my ($prompt,$default) = @_;
239         my $var;
240         print "$prompt\n";
241         print "[\e[1;32m$default\e[0m] -> ";
242         chomp($var = <STDIN>);
243         $var = $default if $var eq "";
244         print "\n";
245         return $var;
246 }
247
248 sub dumphash()
249 {
250         print "\n\e[1;32mPre-build configuration is complete!\e[0m\n\n";
251         print "\e[0mBase install path:\e[1;32m\t\t$main::config{BASE_DIR}\e[0m\n";
252         print "\e[0mConfig path:\e[1;32m\t\t\t$main::config{CONFIG_DIR}\e[0m\n";
253         print "\e[0mData path:\e[1;32m\t\t\t$main::config{DATA_DIR}\e[0m\n";
254         print "\e[0mLog path:\e[1;32m\t\t\t$main::config{LOG_DIR}\e[0m\n";
255         print "\e[0mModule path:\e[1;32m\t\t\t$main::config{MODULE_DIR}\e[0m\n";
256         print "\e[0mCompiler:\e[1;32m\t\t\t$main::cxx{NAME} $main::cxx{VERSION}\e[0m\n";
257         print "\e[0mSocket engine:\e[1;32m\t\t\t$main::config{SOCKETENGINE}\e[0m\n";
258         print "\e[0mGnuTLS support:\e[1;32m\t\t\t$main::config{USE_GNUTLS}\e[0m\n";
259         print "\e[0mOpenSSL support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n";
260 }
261
262 sub showhelp
263 {
264         chomp(my $PWD = `pwd`);
265         my (@socketengines, $SELIST);
266         foreach (<src/socketengines/socketengine_*.cpp>) {
267                 s/src\/socketengines\/socketengine_(\w+)\.cpp/$1/;
268                 push(@socketengines, $1);
269         }
270         $SELIST = join(", ", @socketengines);
271         print <<EOH;
272 Usage: configure [options]
273
274 When no options are specified, interactive
275 configuration is started and you must specify
276 any required values manually. If one or more
277 options are specified, non-interactive configuration
278 is started, and any omitted values are defaulted.
279
280 Arguments with a single \"-\" symbol are also allowed.
281
282   --disable-interactive        Sets no options itself, but
283                                will disable any interactive prompting.
284   --update                     Update makefiles and dependencies
285   --clean                      Remove .config.cache file and go interactive
286   --enable-gnutls              Enable GnuTLS module [no]
287   --enable-openssl             Enable OpenSSL module [no]
288   --socketengine=[name]        Sets the socket engine to be used. Possible values are
289                                $SELIST.
290   --prefix=[directory]         Base directory to install into (if defined,
291                                can automatically define config, data, module,
292                                log and binary dirs as subdirectories of prefix)
293                                [$PWD]
294   --config-dir=[directory]     Config file directory for config and SSL certs
295                                [$PWD/conf]
296   --log-dir=[directory]        Log file directory for logs
297                                [$PWD/logs]
298   --data-dir=[directory]       Data directory for variable data, such as the permchannel
299                                configuration and the XLine database
300                                [$PWD/data]
301   --module-dir=[directory]     Modules directory for loadable modules
302                                [$PWD/modules]
303   --binary-dir=[directory]     Binaries directory for core binary
304                                [$PWD/bin]
305   --list-extras                Show current status of extra modules
306   --enable-extras=[extras]     Enable the specified list of extras
307   --disable-extras=[extras]    Disable the specified list of extras
308   --help                       Show this help text and exit
309
310 EOH
311         exit(0);
312 }
313
314 1;
315