]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - make/configure.pm
Merge pull request #609 from SaberUK/master+configure-sub-shuffle
[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 BEGIN {
25         require 5.8.0;
26 }
27
28 package make::configure;
29
30 use strict;
31 use warnings FATAL => qw(all);
32
33 use Cwd;
34 use Exporter 'import';
35
36 use make::utilities;
37
38 our @EXPORT = qw(cmd_clean cmd_help cmd_update
39                  read_configure_cache write_configure_cache
40                  get_compiler_info find_compiler
41                  run_test test_file test_header
42                  get_property get_revision
43                  dump_hash);
44
45 my $revision;
46
47 sub __get_socketengines() {
48         my @socketengines;
49         foreach (<src/socketengines/socketengine_*.cpp>) {
50                 s/src\/socketengines\/socketengine_(\w+)\.cpp/$1/;
51                 push @socketengines, $1;
52         }
53         return @socketengines;
54 }
55
56 sub cmd_clean {
57         unlink '.config.cache';
58 }
59
60 sub cmd_help {
61         my $PWD = getcwd();
62         my $SELIST = join ', ', __get_socketengines();
63         print <<EOH;
64 Usage: $0 [options]
65
66 When no options are specified, configure runs in interactive mode and you must
67 specify any required values manually. If one or more options are specified,
68 non-interactive configuration is started and any omitted values are defaulted.
69
70 PATH OPTIONS
71
72   --system                      Automatically set up the installation paths
73                                 for system-wide installation.
74   --prefix=[dir]                The root install directory. If this is set then
75                                 all subdirectories will be adjusted accordingly.
76                                 [$PWD/run]
77   --binary-dir=[dir]            The location where the main server binary is
78                                 stored.
79                                 [$PWD/run/bin]
80   --config-dir=[dir]            The location where the configuration files and
81                                 SSL certificates are stored.
82                                 [$PWD/run/conf]
83   --data-dir=[dir]              The location where the data files, such as the
84                                 pid file, are stored.
85                                 [$PWD/run/data]
86   --log-dir=[dir]               The location where the log files are stored.
87                                 [$PWD/run/logs]
88   --module-dir=[dir]            The location where the loadable modules are
89                                 stored.
90                                 [$PWD/run/modules]
91   --build-dir=[dir]             The location to store files in while building.
92
93
94 EXTRA MODULE OPTIONS
95
96   --enable-extras=[extras]      Enables a comma separated list of extra modules.
97   --disable-extras=[extras]     Disables a comma separated list of extra modules.
98   --list-extras                 Shows the availability status of all extra
99                                 modules.
100
101 MISC OPTIONS
102
103   --clean                       Remove the configuration cache file and start
104                                 the interactive configuration wizard.
105   --disable-interactive         Disables the interactive configuration wizard.
106   --help                        Show this message and exit.
107   --uid=[name]                  Sets the user to run InspIRCd as.
108   --socketengine=[name]         Sets the socket engine to be used. Possible
109                                 values are $SELIST.
110   --update                      Updates the build environment.
111
112
113 FLAGS
114
115   CXX=[name]                    Sets the C++ compiler to use when building the
116                                 server. If not specified then the build system
117                                 will search for c++, g++, clang++ or icpc.
118
119 If you have any problems with configuring InspIRCd then visit our IRC channel
120 at irc.ChatSpike.net #InspIRCd.
121
122 EOH
123         exit 0;
124 }
125
126 sub cmd_update {
127         unless (-f '.config.cache') {
128                 print "You have not run $0 before. Please do this before trying to update the build files.\n";
129                 exit 1;
130         }
131         print "Updating...\n";
132         %main::config = read_configure_cache();
133         %main::cxx = get_compiler_info($main::config{CXX});
134         $main::topdir = getcwd();
135         main::writefiles();
136         print "Update complete!\n";
137         exit 0;
138 }
139
140 sub read_configure_cache {
141         my %cfg = ();
142         open(CACHE, '.config.cache') or return %cfg;
143         while (my $line = <CACHE>) {
144                 next if $line =~ /^\s*($|\#)/;
145                 my ($key, $value) = ($line =~ /^(\S+)="(.*)"$/);
146                 $cfg{$key} = $value;
147         }
148         close(CACHE);
149         return %cfg;
150 }
151
152 sub write_configure_cache(%) {
153         my %cfg = @_;
154         open(CACHE, ">.config.cache") or return 0;
155         while (my ($key, $value) = each %cfg) {
156                 $value = "" unless defined $value;
157                 print CACHE "$key=\"$value\"\n";
158         }
159         close(CACHE);
160         return 1;
161 }
162
163 sub get_compiler_info($) {
164         my $binary = shift;
165         my $version = `$binary -v 2>&1`;
166         if ($version =~ /(?:clang|llvm)\sversion\s(\d+\.\d+)/i) {
167                 return (
168                         NAME => 'Clang',
169                         VERSION => $1,
170                         UNSUPPORTED => $1 lt '3.0',
171                         REASON => 'Clang 2.9 and older do not have adequate C++ support.'
172                 );
173         } elsif ($version =~ /gcc\sversion\s(\d+\.\d+)/i) {
174                 return (
175                         NAME => 'GCC',
176                         VERSION => $1,
177                         UNSUPPORTED => $1 lt '4.1',
178                         REASON => 'GCC 4.0 and older do not have adequate C++ support.'
179                 );
180         } elsif ($version =~ /(?:icc|icpc)\sversion\s(\d+\.\d+).\d+\s\(gcc\sversion\s(\d+\.\d+).\d+/i) {
181                 return (
182                         NAME => 'ICC',
183                         VERSION => $1,
184                         UNSUPPORTED => $2 lt '4.1',
185                         REASON => "ICC $1 (GCC $2 compatibility mode) does not have adequate C++ support."
186                 );
187         }
188         return (
189                 NAME => $binary,
190                 VERSION => '0.0'
191         );
192 }
193
194 sub find_compiler {
195         foreach my $compiler ('c++', 'g++', 'clang++', 'icpc') {
196                 return $compiler unless system "$compiler -v > /dev/null 2>&1";
197                 if ($^O eq 'Darwin') {
198                         return $compiler unless system "xcrun $compiler -v > /dev/null 2>&1";
199                 }
200         }
201         return "";
202 }
203
204 sub run_test($$) {
205         my ($what, $result) = @_;
206         print "Checking whether $what is available... ";
207         print $result ? "yes\n" : "no\n";
208         return $result;
209 }
210
211 sub test_file($$;$) {
212         my ($cc, $file, $args) = @_;
213         my $status = 0;
214         $args ||= '';
215         $status ||= system "$cc -o __test_$file make/test/$file $args >/dev/null 2>&1";
216         $status ||= system "./__test_$file >/dev/null 2>&1";
217         unlink  "./__test_$file";
218         return !$status;
219 }
220
221 sub test_header($$;$) {
222         my ($cc, $header, $args) = @_;
223         $args ||= '';
224         open(CC, "| $cc -E - $args >/dev/null 2>&1") or return 0;
225         print CC "#include <$header>";
226         close(CC);
227         return !$?;
228 }
229
230 sub get_property($$;$)
231 {
232         my ($file, $property, $default) = @_;
233         open(MODULE, $file) or return $default;
234         while (<MODULE>) {
235                 if ($_ =~ /^\/\* \$(\S+): (.+) \*\/$/) {
236                         next unless $1 eq $property;
237                         close(MODULE);
238                         return translate_functions($2, $file);
239                 }
240         }
241         close(MODULE);
242         return defined $default ? $default : '';
243 }
244
245 sub get_revision {
246         return $revision if defined $revision;
247         chomp(my $tags = `git describe --tags 2>/dev/null`);
248         $revision = $tags || 'release';
249         return $revision;
250 }
251
252 sub dump_hash()
253 {
254         print "\n\e[1;32mPre-build configuration is complete!\e[0m\n\n";
255         print "\e[0mBase install path:\e[1;32m\t\t$main::config{BASE_DIR}\e[0m\n";
256         print "\e[0mConfig path:\e[1;32m\t\t\t$main::config{CONFIG_DIR}\e[0m\n";
257         print "\e[0mData path:\e[1;32m\t\t\t$main::config{DATA_DIR}\e[0m\n";
258         print "\e[0mLog path:\e[1;32m\t\t\t$main::config{LOG_DIR}\e[0m\n";
259         print "\e[0mModule path:\e[1;32m\t\t\t$main::config{MODULE_DIR}\e[0m\n";
260         print "\e[0mCompiler:\e[1;32m\t\t\t$main::cxx{NAME} $main::cxx{VERSION}\e[0m\n";
261         print "\e[0mSocket engine:\e[1;32m\t\t\t$main::config{SOCKETENGINE}\e[0m\n";
262         print "\e[0mGnuTLS support:\e[1;32m\t\t\t$main::config{USE_GNUTLS}\e[0m\n";
263         print "\e[0mOpenSSL support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n";
264 }
265
266 1;