2 # InspIRCd -- Internet Relay Chat Daemon
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>
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.
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
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/>.
24 package make::configure;
29 use warnings FATAL => qw(all);
31 use Exporter 'import';
34 our @EXPORT = qw(get_compiler_info find_compiler test_file test_header promptnumeric dumphash is_dir getmodules getrevision getcompilerflags getlinkerflags getdependencies nopedantic resolve_directory yesno showhelp promptstring_s module_installed);
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';
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) {
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) {
55 $info{UNSUPPORTED} = $2 lt '4.1';
56 $info{REASON} = "ICC $1 (GCC $2 compatibility mode) does not have adequate C++ support."
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";
72 my ($cc, $file, $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";
81 sub test_header($$;$) {
82 my ($cc, $header, $args) = @_;
84 open(CC, "| $cc -E - $args >/dev/null 2>&1") or return 0;
85 print CC "#include <$header>";
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))
97 $main::config{$flag} = "y";
101 $main::config{$flag} = "n";
106 sub resolve_directory
112 $ret = File::Spec->rel2abs($_[0]);
122 my $data = `git describe --tags 2>/dev/null`;
128 chomp $data; # remove \n
132 sub getcompilerflags {
134 open(FLAGS, $file) or return "";
136 if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/$/) {
137 my $x = translate_functions($1, $file);
149 open(FLAGS, $file) or return "";
151 if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/$/) {
152 my $x = translate_functions($1, $file);
162 sub getdependencies {
164 open(FLAGS, $file) or return "";
166 if ($_ =~ /^\/\* \$ModDep: (.+) \*\/$/) {
167 my $x = translate_functions($1, $file);
179 open(FLAGS, $file) or return "";
181 if ($_ =~ /^\/\* \$NoPedantic \*\/$/) {
182 my $x = translate_functions($_, $file);
200 print "Detecting modules ";
203 opendir(DIRHANDLE, "src/modules") or die("WTF, missing src/modules!");
204 foreach my $name (sort readdir(DIRHANDLE))
206 if ($name =~ /^m_(.+)\.cpp$/)
209 $main::modlist[$i++] = $mod;
220 print "\nOk, $i modules.\n";
224 sub promptnumeric($$)
227 my ($prompt, $configitem) = @_;
230 print "Please enter the maximum $prompt?\n";
231 print "[\e[1;32m$main::config{$configitem}\e[0m] -> ";
232 chomp(my $var = <STDIN>);
235 $var = $main::config{$configitem};
237 if ($var =~ /^\d+$/) {
238 # We don't care what the number is, set it and be on our way.
239 $main::config{$configitem} = $var;
243 print "You must enter a number in this field. Please try again.\n\n";
248 sub module_installed($)
251 eval("use $module;");
255 sub promptstring_s($$)
257 my ($prompt,$default) = @_;
260 print "[\e[1;32m$default\e[0m] -> ";
261 chomp($var = <STDIN>);
262 $var = $default if $var eq "";
269 print "\n\e[1;32mPre-build configuration is complete!\e[0m\n\n";
270 print "\e[0mBase install path:\e[1;32m\t\t$main::config{BASE_DIR}\e[0m\n";
271 print "\e[0mConfig path:\e[1;32m\t\t\t$main::config{CONFIG_DIR}\e[0m\n";
272 print "\e[0mModule path:\e[1;32m\t\t\t$main::config{MODULE_DIR}\e[0m\n";
273 print "\e[0mCompiler:\e[1;32m\t\t\t$main::cxx{NAME} $main::cxx{VERSION}\e[0m\n";
274 print "\e[0mGnuTLS Support:\e[1;32m\t\t\t$main::config{USE_GNUTLS}\e[0m\n";
275 print "\e[0mOpenSSL Support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n\n";
276 print "\e[1;32mImportant note: The maximum length values are now configured in the\e[0m\n";
277 print "\e[1;32m configuration file, not in ./configure! See the <limits>\e[0m\n";
278 print "\e[1;32m tag in the configuration file for more information.\e[0m\n\n";
299 chomp(my $PWD = `pwd`);
301 Usage: configure [options]
303 *** NOTE: NON-INTERACTIVE CONFIGURE IS *NOT* SUPPORTED BY THE ***
304 *** INSPIRCD DEVELOPMENT TEAM. DO NOT ASK FOR HELP REGARDING ***
305 *** NON-INTERACTIVE CONFIGURE ON THE FORUMS OR ON IRC! ***
307 Options: [defaults in brackets after descriptions]
309 When no options are specified, interactive
310 configuration is started and you must specify
311 any required values manually. If one or more
312 options are specified, non-interactive configuration
313 is started, and any omitted values are defaulted.
315 Arguments with a single \"-\" symbol, as in
316 InspIRCd 1.0.x, are also allowed.
318 --disable-interactive Sets no options itself, but
319 will disable any interactive prompting.
320 --update Update makefiles and dependencies
321 --clean Remove .config.cache file and go interactive
322 --enable-gnutls Enable GnuTLS module [no]
323 --enable-openssl Enable OpenSSL module [no]
324 --enable-epoll Enable epoll() where supported [set]
325 --enable-kqueue Enable kqueue() where supported [set]
326 --disable-epoll Do not enable epoll(), fall back
327 to select() [not set]
328 --disable-kqueue Do not enable kqueue(), fall back
329 to select() [not set]
330 --prefix=[directory] Base directory to install into (if defined,
331 can automatically define config, module, bin
332 and library dirs as subdirectories of prefix)
334 --config-dir=[directory] Config file directory for config and SSL certs
336 --log-dir=[directory] Log file directory for logs
338 --data-dir=[directory] Data directory for variable data, such as the permchannel configuration and the XLine database
340 --module-dir=[directory] Modules directory for loadable modules
342 --binary-dir=[directory] Binaries directory for core binary
344 --library-dir=[directory] Library directory for core libraries
346 --list-extras Show current status of extra modules
347 --enable-extras=[extras] Enable the specified list of extras
348 --disable-extras=[extras] Disable the specified list of extras
349 --help Show this help text and exit