]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - make/configure.pm
Merge pull request #608 from SaberUK/master+buildprop-dedupe
[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 run_test test_file test_header promptnumeric dumphash getmodules getrevision get_property 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 run_test($$) {
72         my ($what, $result) = @_;
73         print "Checking whether $what is available... ";
74         print $result ? "yes\n" : "no\n";
75         return $result;
76 }
77
78 sub test_file($$;$) {
79         my ($cc, $file, $args) = @_;
80         my $status = 0;
81         $args ||= '';
82         $status ||= system "$cc -o __test_$file make/test/$file $args >/dev/null 2>&1";
83         $status ||= system "./__test_$file >/dev/null 2>&1";
84         unlink  "./__test_$file";
85         return !$status;
86 }
87
88 sub test_header($$;$) {
89         my ($cc, $header, $args) = @_;
90         $args ||= '';
91         open(CC, "| $cc -E - $args >/dev/null 2>&1") or return 0;
92         print CC "#include <$header>";
93         close(CC);
94         return !$?;
95 }
96
97 sub yesno {
98         my ($flag,$prompt) = @_;
99         print "$prompt [\e[1;32m$main::config{$flag}\e[0m] -> ";
100         chomp(my $tmp = <STDIN>);
101         if ($tmp eq "") { $tmp = $main::config{$flag} }
102         if (($tmp eq "") || ($tmp =~ /^y/i))
103         {
104                 $main::config{$flag} = "y";
105         }
106         else
107         {
108                 $main::config{$flag} = "n";
109         }
110         return;
111 }
112
113 sub get_property($$;$)
114 {
115         my ($file, $property, $default) = @_;
116         open(MODULE, $file) or return $default;
117         while (<MODULE>) {
118                 if ($_ =~ /^\/\* \$(\S+): (.+) \*\/$/) {
119                         next unless $1 eq $property;
120                         close(MODULE);
121                         return translate_functions($2, $file);
122                 }
123         }
124         close(MODULE);
125         return defined $default ? $default : '';
126 }
127
128 sub getrevision {
129         return $revision if defined $revision;
130         chomp(my $tags = `git describe --tags 2>/dev/null`);
131         $revision = $tags || 'release';
132         return $revision;
133 }
134
135 sub getmodules
136 {
137         my ($silent) = @_;
138
139         my $i = 0;
140
141         if (!$silent)
142         {
143                 print "Detecting modules ";
144         }
145
146         opendir(DIRHANDLE, "src/modules") or die("WTF, missing src/modules!");
147         foreach my $name (sort readdir(DIRHANDLE))
148         {
149                 if ($name =~ /^m_(.+)\.cpp$/)
150                 {
151                         my $mod = $1;
152                         $main::modlist[$i++] = $mod;
153                         if (!$silent)
154                         {
155                                 print ".";
156                         }
157                 }
158         }
159         closedir(DIRHANDLE);
160
161         if (!$silent)
162         {
163                 print "\nOk, $i modules.\n";
164         }
165 }
166
167 sub promptnumeric($$)
168 {
169         my $continue = 0;
170         my ($prompt, $configitem) = @_;
171         while (!$continue)
172         {
173                 print "Please enter the maximum $prompt?\n";
174                 print "[\e[1;32m$main::config{$configitem}\e[0m] -> ";
175                 chomp(my $var = <STDIN>);
176                 if ($var eq "")
177                 {
178                         $var = $main::config{$configitem};
179                 }
180                 if ($var =~ /^\d+$/) {
181                         # We don't care what the number is, set it and be on our way.
182                         $main::config{$configitem} = $var;
183                         $continue = 1;
184                         print "\n";
185                 } else {
186                         print "You must enter a number in this field. Please try again.\n\n";
187                 }
188         }
189 }
190
191 sub module_installed($)
192 {
193         my $module = shift;
194         eval("use $module;");
195         return !$@;
196 }
197
198 sub promptstring_s($$)
199 {
200         my ($prompt,$default) = @_;
201         my $var;
202         print "$prompt\n";
203         print "[\e[1;32m$default\e[0m] -> ";
204         chomp($var = <STDIN>);
205         $var = $default if $var eq "";
206         print "\n";
207         return $var;
208 }
209
210 sub dumphash()
211 {
212         print "\n\e[1;32mPre-build configuration is complete!\e[0m\n\n";
213         print "\e[0mBase install path:\e[1;32m\t\t$main::config{BASE_DIR}\e[0m\n";
214         print "\e[0mConfig path:\e[1;32m\t\t\t$main::config{CONFIG_DIR}\e[0m\n";
215         print "\e[0mData path:\e[1;32m\t\t\t$main::config{DATA_DIR}\e[0m\n";
216         print "\e[0mLog path:\e[1;32m\t\t\t$main::config{LOG_DIR}\e[0m\n";
217         print "\e[0mModule path:\e[1;32m\t\t\t$main::config{MODULE_DIR}\e[0m\n";
218         print "\e[0mCompiler:\e[1;32m\t\t\t$main::cxx{NAME} $main::cxx{VERSION}\e[0m\n";
219         print "\e[0mSocket engine:\e[1;32m\t\t\t$main::config{SOCKETENGINE}\e[0m\n";
220         print "\e[0mGnuTLS support:\e[1;32m\t\t\t$main::config{USE_GNUTLS}\e[0m\n";
221         print "\e[0mOpenSSL support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n";
222 }
223
224 sub showhelp
225 {
226         chomp(my $PWD = `pwd`);
227         my (@socketengines, $SELIST);
228         foreach (<src/socketengines/socketengine_*.cpp>) {
229                 s/src\/socketengines\/socketengine_(\w+)\.cpp/$1/;
230                 push(@socketengines, $1);
231         }
232         $SELIST = join(", ", @socketengines);
233         print <<EOH;
234 Usage: configure [options]
235
236 When no options are specified, interactive
237 configuration is started and you must specify
238 any required values manually. If one or more
239 options are specified, non-interactive configuration
240 is started, and any omitted values are defaulted.
241
242 Arguments with a single \"-\" symbol are also allowed.
243
244   --disable-interactive        Sets no options itself, but
245                                will disable any interactive prompting.
246   --update                     Update makefiles and dependencies
247   --clean                      Remove .config.cache file and go interactive
248   --enable-gnutls              Enable GnuTLS module [no]
249   --enable-openssl             Enable OpenSSL module [no]
250   --socketengine=[name]        Sets the socket engine to be used. Possible values are
251                                $SELIST.
252   --prefix=[directory]         Base directory to install into (if defined,
253                                can automatically define config, data, module,
254                                log and binary dirs as subdirectories of prefix)
255                                [$PWD]
256   --config-dir=[directory]     Config file directory for config and SSL certs
257                                [$PWD/conf]
258   --log-dir=[directory]        Log file directory for logs
259                                [$PWD/logs]
260   --data-dir=[directory]       Data directory for variable data, such as the permchannel
261                                configuration and the XLine database
262                                [$PWD/data]
263   --module-dir=[directory]     Modules directory for loadable modules
264                                [$PWD/modules]
265   --binary-dir=[directory]     Binaries directory for core binary
266                                [$PWD/bin]
267   --list-extras                Show current status of extra modules
268   --enable-extras=[extras]     Enable the specified list of extras
269   --disable-extras=[extras]    Disable the specified list of extras
270   --help                       Show this help text and exit
271
272 EOH
273         exit(0);
274 }
275
276 1;
277