summaryrefslogtreecommitdiff
path: root/make
diff options
context:
space:
mode:
Diffstat (limited to 'make')
-rwxr-xr-xmake/calcdep.pl183
-rw-r--r--make/common.pm131
-rw-r--r--make/configure.pm525
-rw-r--r--make/console.pm163
-rw-r--r--make/directive.pm309
-rw-r--r--make/gnutlscert.pm150
-rw-r--r--make/opensslcert.pm66
-rwxr-xr-xmake/run-cc.pl237
-rw-r--r--make/template/bsd.mk33
-rw-r--r--make/template/config.h (renamed from make/check_strlcpy.cpp)22
-rw-r--r--make/template/gdbargs4
-rw-r--r--make/template/inspircd73
-rw-r--r--make/template/inspircd-genssl.146
-rw-r--r--make/template/inspircd.1108
-rw-r--r--make/template/inspircd.service37
-rw-r--r--make/template/main.mk301
-rw-r--r--make/template/org.inspircd.plist5
-rw-r--r--make/test/arc4random_buf.cpp (renamed from make/check_epoll.cpp)9
-rw-r--r--make/test/clock_gettime.cpp (renamed from make/check_stdint.cpp)9
-rw-r--r--make/test/compiler.cpp39
-rw-r--r--make/test/compiler_info.cpp41
-rw-r--r--make/test/eventfd.cpp (renamed from make/check_eventfd.cpp)0
-rw-r--r--make/test/kqueue.cpp (renamed from make/check_kqueue.cpp)2
-rwxr-xr-xmake/unit-cc.pl100
-rw-r--r--make/utilities.pm471
25 files changed, 1515 insertions, 1549 deletions
diff --git a/make/calcdep.pl b/make/calcdep.pl
index 49506dd3b..279fdffce 100755
--- a/make/calcdep.pl
+++ b/make/calcdep.pl
@@ -19,15 +19,29 @@
#
+BEGIN {
+ require 5.10.0;
+ unless (-f 'configure') {
+ print "Error: $0 must be run from the main source directory!\n";
+ exit 1;
+ }
+}
+
use strict;
-use warnings;
-use POSIX qw(getcwd);
+use warnings FATAL => qw(all);
+
+use File::Basename qw(basename);
+
+use constant {
+ BUILDPATH => $ENV{BUILDPATH},
+ SOURCEPATH => $ENV{SOURCEPATH}
+};
sub find_output;
sub gendep($);
sub dep_cpp($$$);
sub dep_so($);
-sub dep_dir($);
+sub dep_dir($$);
sub run();
my %f2dep;
@@ -36,30 +50,20 @@ run;
exit 0;
sub run() {
- my $build = $ENV{BUILDPATH};
- mkdir $build;
- chdir $build or die "Could not open build directory: $!";
+ mkdir BUILDPATH;
+ chdir BUILDPATH or die "Could not open build directory: $!";
unlink 'include';
- symlink "$ENV{SOURCEPATH}/include", 'include';
+ symlink "${\SOURCEPATH}/include", 'include';
mkdir $_ for qw/bin modules obj/;
-# BSD make has a horribly annoying bug resulting in an extra chdir of the make process
-# Create symlinks to work around it
- symlink "../$_", "obj/$_" for qw/bin modules obj/;
- $build = getcwd();
open MAKE, '>real.mk' or die "Could not write real.mk: $!";
- chdir "$ENV{SOURCEPATH}/src";
+ chdir "${\SOURCEPATH}/src";
- if ($ENV{PURE_STATIC}) {
- run_static();
- } else {
- run_dynamic();
- }
+ run_dynamic();
close MAKE;
}
sub run_dynamic() {
- my $build = $ENV{BUILDPATH};
print MAKE <<END;
# DO NOT EDIT THIS FILE
# It is autogenerated by make/calcdep.pl, and will be overwritten
@@ -71,113 +75,68 @@ bad-target:
\@echo "in order to set the correct environment variables"
\@exit 1
-all: inspircd commands modules
+all: inspircd modules
END
- my(@core_deps, @cmdlist, @modlist);
- for my $file (<*.cpp>, <modes/*.cpp>, <socketengines/*.cpp>, "threadengines/threadengine_pthread.cpp") {
+ my(@core_deps, @modlist);
+ for my $file (<*.cpp>, <socketengines/*.cpp>, "threadengines/threadengine_pthread.cpp") {
my $out = find_output $file;
dep_cpp $file, $out, 'gen-o';
- next if $file =~ m#^socketengines/# && $file ne "socketengines/$ENV{SOCKETENGINE}.cpp";
+ next if $file =~ m#^socketengines/# && $file ne "socketengines/socketengine_$ENV{SOCKETENGINE}.cpp";
+ # Having a module in the src directory is a bad idea because it will be linked to the core binary
+ if ($file =~ /^(m|core)_.*\.cpp/) {
+ my $correctsubdir = ($file =~ /^m_/ ? "modules" : "coremods");
+ print "Error: module $file is in the src directory, put it in src/$correctsubdir instead!\n";
+ exit 1;
+ }
push @core_deps, $out;
}
- for my $file (<commands/*.cpp>) {
- my $out = dep_so $file;
- push @cmdlist, $out;
- }
-
- opendir my $moddir, 'modules';
- for my $file (sort readdir $moddir) {
- next if $file =~ /^\./;
- if (-e "modules/extra/$file" && !-l "modules/$file") {
- # Incorrect symlink?
- print "Replacing symlink for $file found in modules/extra\n";
- rename "modules/$file", "modules/$file~";
- symlink "extra/$file", "modules/$file";
- }
- if ($file =~ /^m_/ && -d "modules/$file" && dep_dir "modules/$file") {
- mkdir "$build/obj/$file";
- push @modlist, "modules/$file.so";
- }
- if ($file =~ /^m_.*\.cpp$/) {
- my $out = dep_so "modules/$file";
- push @modlist, $out;
+ foreach my $directory (qw(coremods modules)) {
+ opendir(my $moddir, $directory);
+ for my $file (sort readdir $moddir) {
+ next if $file =~ /^\./;
+ if ($directory eq 'modules' && -e "modules/extra/$file" && !-l "modules/$file") {
+ # Incorrect symlink?
+ print "Replacing symlink for $file found in modules/extra\n";
+ rename "modules/$file", "modules/$file~";
+ symlink "extra/$file", "modules/$file";
+ }
+ if ($file =~ /^(?:core|m)_/ && -d "$directory/$file" && dep_dir "$directory/$file", "modules/$file") {
+ mkdir "${\BUILDPATH}/obj/$file";
+ push @modlist, "modules/$file.so";
+ }
+ if ($file =~ /^.*\.cpp$/) {
+ my $out = dep_so "$directory/$file";
+ push @modlist, $out;
+ }
}
}
-
+
my $core_mk = join ' ', @core_deps;
- my $cmds = join ' ', @cmdlist;
my $mods = join ' ', @modlist;
print MAKE <<END;
bin/inspircd: $core_mk
- @\$(SOURCEPATH)/make/unit-cc.pl core-ld\$(VERBOSE) \$\@ \$^ \$>
+ @\$(SOURCEPATH)/make/unit-cc.pl core-ld \$\@ \$^ \$>
inspircd: bin/inspircd
-commands: $cmds
-
modules: $mods
-.PHONY: all bad-target inspircd commands modules
-
-END
-}
-
-sub run_static() {
- print MAKE <<END;
-# DO NOT EDIT THIS FILE
-# It is autogenerated by make/calcdep.pl, and will be overwritten
-# every time you rerun make in the main directory
-VPATH = \$(SOURCEPATH)/src
-
-bad-target:
- \@echo "This Makefile must be run by a sub-make from the source"
- \@echo "in order to set the correct environment variables"
- \@exit 1
-
-all: inspircd
-
-END
- my(@deps, @srcs);
- for my $file (<*.cpp>, <modes/*.cpp>, <socketengines/*.cpp>, <commands/*.cpp>,
- <modules/*.cpp>, <modules/m_*/*.cpp>, "threadengines/threadengine_pthread.cpp") {
- my $out = find_output $file, 1;
- if ($out =~ m#obj/([^/]+)/[^/]+.o$#) {
- mkdir "$ENV{BUILDPATH}/obj/$1";
- }
- dep_cpp $file, $out, 'gen-o';
- next if $file =~ m#^socketengines/# && $file ne "socketengines/$ENV{SOCKETENGINE}.cpp";
- push @deps, $out;
- push @srcs, $file;
- }
-
- my $core_mk = join ' ', @deps;
- my $core_src = join ' ', @srcs;
- print MAKE <<END;
-
-obj/ld-extra.cmd: $core_src
- \@\$(SOURCEPATH)/make/unit-cc.pl gen-ld\$(VERBOSE) \$\@ \$^ \$>
-
-bin/inspircd: $core_mk obj/ld-extra.cmd
- \@\$(SOURCEPATH)/make/unit-cc.pl static-ld\$(VERBOSE) \$\@ \$^ \$>
-
-inspircd: bin/inspircd
-
-.PHONY: all bad-target inspircd
+.PHONY: all bad-target inspircd modules
END
}
sub find_output {
- my($file, $static) = @_;
+ my $file = shift;
my($path,$base) = $file =~ m#^((?:.*/)?)([^/]+)\.cpp# or die "Bad file $file";
- if ($path eq 'modules/' || $path eq 'commands/') {
- return $static ? "obj/$base.o" : "modules/$base.so";
+ if ($path eq 'modules/' || $path eq 'coremods/') {
+ return "modules/$base.so";
} elsif ($path eq '' || $path eq 'modes/' || $path =~ /^[a-z]+engines\/$/) {
return "obj/$base.o";
- } elsif ($path =~ m#modules/(m_.*)/#) {
+ } elsif ($path =~ m#modules/(m_.*)/# || $path =~ m#coremods/(core_.*)/#) {
return "obj/$1/$base.o";
} else {
die "Can't determine output for $file";
@@ -199,7 +158,7 @@ sub gendep($) {
while (<$in>) {
if (/^\s*#\s*include\s*"([^"]+)"/) {
my $inc = $1;
- next if $inc eq 'inspircd_version.h' && $f eq '../include/inspircd.h';
+ next if $inc eq 'config.h' && $f eq '../include/inspircd.h';
my $found = 0;
for my $loc ("$basedir/$inc", "../include/$inc") {
next unless -e $loc;
@@ -225,26 +184,23 @@ sub dep_cpp($$$) {
gendep $file;
print MAKE "$out: $file $f2dep{$file}\n";
- print MAKE "\t@\$(SOURCEPATH)/make/unit-cc.pl $type\$(VERBOSE) \$\@ \$(SOURCEPATH)/src/$file \$>\n";
+ print MAKE "\t@\$(SOURCEPATH)/make/unit-cc.pl $type \$\@ \$(SOURCEPATH)/src/$file \$>\n";
}
sub dep_so($) {
my($file) = @_;
my $out = find_output $file;
- my $split = find_output $file, 1;
- if ($ENV{SPLIT_CC}) {
- dep_cpp $file, $split, 'gen-o';
- print MAKE "$out: $split\n";
- print MAKE "\t@\$(SOURCEPATH)/make/unit-cc.pl link-so\$(VERBOSE) \$\@ \$(SOURCEPATH)/src/$file \$>\n";
- } else {
- dep_cpp $file, $out, 'gen-so';
- }
+ my $name = basename $out, '.so';
+ print MAKE ".PHONY: $name\n";
+ print MAKE "$name: $out\n";
+
+ dep_cpp $file, $out, 'gen-so';
return $out;
}
-sub dep_dir($) {
- my($dir) = @_;
+sub dep_dir($$) {
+ my($dir, $outdir) = @_;
my @ofiles;
opendir DIR, $dir;
for my $file (sort readdir DIR) {
@@ -256,8 +212,11 @@ sub dep_dir($) {
closedir DIR;
if (@ofiles) {
my $ofiles = join ' ', @ofiles;
- print MAKE "$dir.so: $ofiles\n";
- print MAKE "\t@\$(SOURCEPATH)/make/unit-cc.pl link-dir\$(VERBOSE) \$\@ \$^ \$>\n";
+ my $name = basename $outdir;
+ print MAKE ".PHONY: $name\n";
+ print MAKE "$name: $outdir.so\n";
+ print MAKE "$outdir.so: $ofiles\n";
+ print MAKE "\t@\$(SOURCEPATH)/make/unit-cc.pl link-dir \$\@ ${\SOURCEPATH}/src/$dir \$^ \$>\n";
return 1;
} else {
return 0;
diff --git a/make/common.pm b/make/common.pm
new file mode 100644
index 000000000..ba6b03f87
--- /dev/null
+++ b/make/common.pm
@@ -0,0 +1,131 @@
+#
+# InspIRCd -- Internet Relay Chat Daemon
+#
+# Copyright (C) 2013-2017 Peter Powell <petpow@saberuk.com>
+#
+# This file is part of InspIRCd. InspIRCd is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+BEGIN {
+ require 5.10.0;
+}
+
+package make::common;
+
+use feature ':5.10';
+use strict;
+use warnings FATAL => qw(all);
+
+use Exporter qw(import);
+use File::Path qw(mkpath);
+use File::Spec::Functions qw(rel2abs);
+
+use make::console;
+
+our @EXPORT = qw(create_directory
+ get_cpu_count
+ get_version
+ read_config_file
+ write_config_file);
+
+sub create_directory($$) {
+ my ($location, $permissions) = @_;
+ return eval {
+ mkpath($location, 0, $permissions);
+ return 1;
+ } // 0;
+}
+
+sub get_version {
+ state %version;
+ return %version if %version;
+
+ # Attempt to retrieve version information from src/version.sh
+ chomp(my $vf = `sh src/version.sh 2>/dev/null`);
+ if ($vf =~ /^InspIRCd-([0-9]+)\.([0-9]+)\.([0-9]+)(?:-(\w+))?$/) {
+ %version = ( MAJOR => $1, MINOR => $2, PATCH => $3, LABEL => $4 );
+ }
+
+ # Attempt to retrieve missing version information from Git
+ chomp(my $gr = `git describe --tags 2>/dev/null`);
+ if ($gr =~ /^v([0-9]+)\.([0-9]+)\.([0-9]+)(?:[a-z]+\d+)?(?:-\d+-g(\w+))?$/) {
+ $version{MAJOR} //= $1;
+ $version{MINOR} //= $2;
+ $version{PATCH} //= $3;
+ $version{LABEL} = $4 if defined $4;
+ }
+
+ # If the user has specified a distribution label then we use it in
+ # place of the label from src/version.sh or Git.
+ $version{LABEL} = shift // $version{LABEL};
+
+ # If any of these fields are missing then the user has deleted the
+ # version file and is not running from Git. Fill in the fields with
+ # dummy data so we don't get into trouble with undef values later.
+ $version{MAJOR} //= '0';
+ $version{MINOR} //= '0';
+ $version{PATCH} //= '0';
+
+ # If there is no label then the user is using a stable release which
+ # does not have a label attached.
+ if (defined $version{LABEL}) {
+ $version{FULL} = "$version{MAJOR}.$version{MINOR}.$version{PATCH}-$version{LABEL}"
+ } else {
+ $version{LABEL} = 'release';
+ $version{FULL} = "$version{MAJOR}.$version{MINOR}.$version{PATCH}"
+ }
+
+ return %version;
+}
+
+sub get_cpu_count {
+ my $count = 1;
+ if ($^O =~ /bsd/) {
+ $count = `sysctl -n hw.ncpu 2>/dev/null` || 1;
+ } elsif ($^O eq 'darwin') {
+ $count = `sysctl -n hw.activecpu 2>/dev/null` || 1;
+ } elsif ($^O eq 'linux') {
+ $count = `getconf _NPROCESSORS_ONLN 2>/dev/null` || 1;
+ } elsif ($^O eq 'solaris') {
+ $count = `psrinfo -p 2>/dev/null` || 1;
+ }
+ chomp($count);
+ return $count;
+}
+
+sub read_config_file($) {
+ my $path = shift;
+ my %config;
+ open(my $fh, $path) or return %config;
+ while (my $line = <$fh>) {
+ next if $line =~ /^\s*($|\#)/;
+ my ($key, $value) = ($line =~ /^(\S+)(?:\s(.*))?$/);
+ $config{$key} = $value;
+ }
+ close $fh;
+ return %config;
+}
+
+sub write_config_file($%) {
+ my $path = shift;
+ my %config = @_;
+ open(my $fh, '>', $path) or print_error "unable to write to $path: $!";
+ while (my ($key, $value) = each %config) {
+ $value //= '';
+ say $fh "$key $value";
+ }
+ close $fh;
+}
+
+1;
diff --git a/make/configure.pm b/make/configure.pm
index 9b8e2d0e4..877e4ce6c 100644
--- a/make/configure.pm
+++ b/make/configure.pm
@@ -1,7 +1,7 @@
#
# InspIRCd -- Internet Relay Chat Daemon
#
-# Copyright (C) 2012 Peter Powell <petpow@saberuk.com>
+# Copyright (C) 2012-2017 Peter Powell <petpow@saberuk.com>
# Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
# Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
# Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
@@ -21,289 +21,320 @@
#
-package make::configure;
+BEGIN {
+ require 5.10.0;
+}
-require 5.8.0;
+package make::configure;
+use feature ':5.10';
use strict;
use warnings FATAL => qw(all);
-use Exporter 'import';
-use POSIX;
-use make::utilities;
-our @EXPORT = qw(promptnumeric dumphash is_dir getmodules getrevision getcompilerflags getlinkerflags getdependencies nopedantic resolve_directory yesno showhelp promptstring_s module_installed);
-
-my $no_git = 0;
-
-sub yesno {
- my ($flag,$prompt) = @_;
- print "$prompt [\e[1;32m$main::config{$flag}\e[0m] -> ";
- chomp(my $tmp = <STDIN>);
- if ($tmp eq "") { $tmp = $main::config{$flag} }
- if (($tmp eq "") || ($tmp =~ /^y/i))
- {
- $main::config{$flag} = "y";
+use Cwd qw(getcwd);
+use Exporter qw(import);
+use File::Basename qw(basename dirname);
+use File::Spec::Functions qw(catdir catfile);
+
+use make::common;
+use make::console;
+
+use constant CONFIGURE_ROOT => dirname dirname __FILE__;
+use constant CONFIGURE_DIRECTORY => catdir(CONFIGURE_ROOT, '.configure');
+use constant CONFIGURE_CACHE_FILE => catfile(CONFIGURE_DIRECTORY, 'cache.cfg');
+use constant CONFIGURE_CACHE_VERSION => '1';
+use constant CONFIGURE_ERROR_PIPE => $ENV{INSPIRCD_VERBOSE} ? '' : '1>/dev/null 2>/dev/null';
+
+our @EXPORT = qw(CONFIGURE_CACHE_FILE
+ CONFIGURE_CACHE_VERSION
+ cmd_clean
+ cmd_help
+ cmd_update
+ run_test
+ test_file
+ test_header
+ write_configure_cache
+ get_compiler_info
+ find_compiler
+ parse_templates);
+
+sub __get_socketengines {
+ my @socketengines;
+ foreach (<src/socketengines/socketengine_*.cpp>) {
+ s/src\/socketengines\/socketengine_(\w+)\.cpp/$1/;
+ push @socketengines, $1;
}
- else
- {
- $main::config{$flag} = "n";
- }
- return;
+ return @socketengines;
}
-sub resolve_directory
-{
- my $ret = $_[0];
- eval
- {
- use File::Spec;
- $ret = File::Spec->rel2abs($_[0]);
- };
- return $ret;
-}
+# TODO: when buildtool is done this can be mostly removed with
+# the remainder being merged into parse_templates.
+sub __get_template_settings($$$) {
+
+ # These are actually hash references
+ my ($config, $compiler, $version) = @_;
-sub getrevision {
- if ($no_git)
- {
- return "0";
+ # Start off by populating with the config
+ my %settings = %$config;
+
+ # Compiler information
+ while (my ($key, $value) = each %{$compiler}) {
+ $settings{'COMPILER_' . $key} = $value;
}
- my $data = `git describe --tags 2>/dev/null`;
- if ($data eq "")
- {
- $no_git = 1;
- return '0';
+
+ # Version information
+ while (my ($key, $value) = each %{$version}) {
+ $settings{'VERSION_' . $key} = $value;
}
- chomp $data; # remove \n
- return $data;
+
+ # Miscellaneous information
+ $settings{CONFIGURE_DIRECTORY} = CONFIGURE_DIRECTORY;
+ $settings{CONFIGURE_CACHE_FILE} = CONFIGURE_CACHE_FILE;
+ $settings{SYSTEM_NAME} = lc $^O;
+
+ return %settings;
}
-sub getcompilerflags {
- my ($file) = @_;
- open(FLAGS, $file) or return "";
- while (<FLAGS>) {
- if ($_ =~ /^\/\* \$CompileFlags: (.+) \*\/\r?$/) {
- my $x = translate_functions($1, $file);
- next if ($x eq "");
- close(FLAGS);
- return $x;
- }
- }
- close(FLAGS);
- return "";
+sub __test_compiler($) {
+ my $compiler = shift;
+ return 0 unless run_test("`$compiler`", !system "$compiler -v ${\CONFIGURE_ERROR_PIPE}");
+ return 0 unless run_test("`$compiler`", test_file($compiler, 'compiler.cpp', '-fno-rtti'), 'compatible');
+ return 1;
}
-sub getlinkerflags {
- my ($file) = @_;
- open(FLAGS, $file) or return "";
- while (<FLAGS>) {
- if ($_ =~ /^\/\* \$LinkerFlags: (.+) \*\/\r?$/) {
- my $x = translate_functions($1, $file);
- next if ($x eq "");
- close(FLAGS);
- return $x;
- }
- }
- close(FLAGS);
- return "";
+sub cmd_clean {
+ unlink CONFIGURE_CACHE_FILE;
}
-sub getdependencies {
- my ($file) = @_;
- open(FLAGS, $file) or return "";
- while (<FLAGS>) {
- if ($_ =~ /^\/\* \$ModDep: (.+) \*\/\r?$/) {
- my $x = translate_functions($1, $file);
- next if ($x eq "");
- close(FLAGS);
- return $x;
- }
- }
- close(FLAGS);
- return "";
+sub cmd_help {
+ my $PWD = getcwd();
+ my $SELIST = join ', ', __get_socketengines();
+ print <<EOH;
+Usage: $0 [options]
+
+When no options are specified, configure runs in interactive mode and you must
+specify any required values manually. If one or more options are specified,
+non-interactive configuration is started and any omitted values are defaulted.
+
+PATH OPTIONS
+
+ --system Automatically set up the installation paths
+ for system-wide installation.
+ --prefix=[dir] The root install directory. If this is set then
+ all subdirectories will be adjusted accordingly.
+ [$PWD/run]
+ --binary-dir=[dir] The location where the main server binary is
+ stored.
+ [$PWD/run/bin]
+ --config-dir=[dir] The location where the configuration files and
+ SSL certificates are stored.
+ [$PWD/run/conf]
+ --data-dir=[dir] The location where the data files, such as the
+ pid file, are stored.
+ [$PWD/run/data]
+ --log-dir=[dir] The location where the log files are stored.
+ [$PWD/run/logs]
+ --manual-dir=[dir] The location where the manual files are stored.
+ [$PWD/run/manuals]
+ --module-dir=[dir] The location where the loadable modules are
+ stored.
+ [$PWD/run/modules]
+ --script-dir=[dir] The location where the scripts, such as the
+ init scripts, are stored.
+ [$PWD/run]
+
+EXTRA MODULE OPTIONS
+
+ --enable-extras=[extras] Enables a comma separated list of extra modules.
+ --disable-extras=[extras] Disables a comma separated list of extra modules.
+ --list-extras Shows the availability status of all extra
+ modules.
+
+MISC OPTIONS
+
+ --clean Remove the configuration cache file and start
+ the interactive configuration wizard.
+ --disable-interactive Disables the interactive configuration wizard.
+ --distribution-label=[text] Sets a distribution specific version label in
+ the build configuration.
+ --gid=[id|name] Sets the group to run InspIRCd as.
+ --help Show this message and exit.
+ --socketengine=[name] Sets the socket engine to be used. Possible
+ values are $SELIST.
+ --uid=[id|name] Sets the user to run InspIRCd as.
+ --update Updates the build environment with the settings
+ from the cache.
+
+
+FLAGS
+
+ CXX=[name] Sets the C++ compiler to use when building the
+ server. If not specified then the build system
+ will search for c++, g++, clang++ or icpc.
+
+If you have any problems with configuring InspIRCd then visit our IRC channel
+at irc.inspircd.org #InspIRCd for support.
+
+EOH
+ exit 0;
}
-sub nopedantic {
- my ($file) = @_;
- open(FLAGS, $file) or return "";
- while (<FLAGS>) {
- if ($_ =~ /^\/\* \$NoPedantic \*\/\r?$/) {
- my $x = translate_functions($_, $file);
- next if ($x eq "");
- close(FLAGS);
- return 1;
- }
- }
- close(FLAGS);
- return 0;
+sub cmd_update {
+ print_error "You have not run $0 before. Please do this before trying to update the generated files." unless -f CONFIGURE_CACHE_FILE;
+ say 'Updating...';
+ my %config = read_config_file(CONFIGURE_CACHE_FILE);
+ my %compiler = get_compiler_info($config{CXX});
+ my %version = get_version $config{DISTRIBUTION};
+ parse_templates(\%config, \%compiler, \%version);
+ say 'Update complete!';
+ exit 0;
}
-sub getmodules
-{
- my ($silent) = @_;
+sub run_test($$;$) {
+ my ($what, $result, $adjective) = @_;
+ $adjective //= 'available';
+ print_format "Checking whether <|GREEN $what|> is $adjective ... ";
+ print_format $result ? "<|GREEN yes|>\n" : "<|RED no|>\n";
+ return $result;
+}
- my $i = 0;
+sub test_file($$;$) {
+ my ($compiler, $file, $args) = @_;
+ my $status = 0;
+ $args //= '';
+ $status ||= system "$compiler -o __test_$file ${\CONFIGURE_ROOT}/make/test/$file $args ${\CONFIGURE_ERROR_PIPE}";
+ $status ||= system "./__test_$file ${\CONFIGURE_ERROR_PIPE}";
+ unlink "./__test_$file";
+ return !$status;
+}
- if (!$silent)
- {
- print "Detecting modules ";
- }
+sub test_header($$;$) {
+ my ($compiler, $header, $args) = @_;
+ $args //= '';
+ open(my $fh, "| $compiler -E - $args ${\CONFIGURE_ERROR_PIPE}") or return 0;
+ print $fh "#include <$header>";
+ close $fh;
+ return !$?;
+}
- opendir(DIRHANDLE, "src/modules") or die("WTF, missing src/modules!");
- foreach my $name (sort readdir(DIRHANDLE))
- {
- if ($name =~ /^m_(.+)\.cpp$/)
- {
- my $mod = $1;
- $main::modlist[$i++] = $mod;
- if (!$silent)
- {
- print ".";
- }
- }
+sub write_configure_cache(%) {
+ unless (-e CONFIGURE_DIRECTORY) {
+ print_format "Creating <|GREEN ${\CONFIGURE_DIRECTORY}|> ...\n";
+ create_directory CONFIGURE_DIRECTORY, 0750 or print_error "unable to create ${\CONFIGURE_DIRECTORY}: $!";
}
- closedir(DIRHANDLE);
- if (!$silent)
- {
- print "\nOk, $i modules.\n";
- }
+ print_format "Writing <|GREEN ${\CONFIGURE_CACHE_FILE}|> ...\n";
+ my %config = @_;
+ write_config_file CONFIGURE_CACHE_FILE, %config;
}
-sub promptnumeric($$)
-{
- my $continue = 0;
- my ($prompt, $configitem) = @_;
- while (!$continue)
- {
- print "Please enter the maximum $prompt?\n";
- print "[\e[1;32m$main::config{$configitem}\e[0m] -> ";
- chomp(my $var = <STDIN>);
- if ($var eq "")
- {
- $var = $main::config{$configitem};
- }
- if ($var =~ /^\d+$/) {
- # We don't care what the number is, set it and be on our way.
- $main::config{$configitem} = $var;
- $continue = 1;
- print "\n";
- } else {
- print "You must enter a number in this field. Please try again.\n\n";
- }
+sub get_compiler_info($) {
+ my $binary = shift;
+ my %info = (NAME => 'Unknown', VERSION => '0.0');
+ return %info if system "$binary -o __compiler_info ${\CONFIGURE_ROOT}/make/test/compiler_info.cpp ${\CONFIGURE_ERROR_PIPE}";
+ open(my $fh, '-|', './__compiler_info 2>/dev/null');
+ while (my $line = <$fh>) {
+ $info{$1} = $2 if $line =~ /^([A-Z]+)\s(.+)$/;
}
+ close $fh;
+ unlink './__compiler_info';
+ return %info;
}
-sub module_installed($)
-{
- my $module = shift;
- eval("use $module;");
- return !$@;
+sub find_compiler {
+ my @compilers = qw(c++ g++ clang++ icpc);
+ foreach my $compiler (shift // @compilers) {
+ return $compiler if __test_compiler $compiler;
+ return "xcrun $compiler" if $^O eq 'darwin' && __test_compiler "xcrun $compiler";
+ }
}
-sub promptstring_s($$)
-{
- my ($prompt,$default) = @_;
- my $var;
- print "$prompt\n";
- print "[\e[1;32m$default\e[0m] -> ";
- chomp($var = <STDIN>);
- $var = $default if $var eq "";
- print "\n";
- return $var;
-}
+sub parse_templates($$$) {
+
+ # These are actually hash references
+ my ($config, $compiler, $version) = @_;
+
+ # Collect settings to be used when generating files
+ my %settings = __get_template_settings($config, $compiler, $version);
+
+ # Iterate through files in make/template.
+ foreach (<make/template/*>) {
+ print_format "Parsing <|GREEN $_|> ...\n";
+ open(my $fh, $_) or print_error "unable to read $_: $!";
+ my (@lines, $mode, @platforms, @targets);
+
+ # First pass: parse template variables and directives.
+ while (my $line = <$fh>) {
+ chomp $line;
+
+ # Does this line match a variable?
+ while ($line =~ /(@(\w+?)@)/) {
+ my ($variable, $name) = ($1, $2);
+ if (defined $settings{$name}) {
+ $line =~ s/\Q$variable\E/$settings{$name}/;
+ } else {
+ print_warning "unknown template variable '$name' in $_!";
+ last;
+ }
+ }
-sub dumphash()
-{
- print "\n\e[1;32mPre-build configuration is complete!\e[0m\n\n";
- print "\e[0mBase install path:\e[1;32m\t\t$main::config{BASE_DIR}\e[0m\n";
- print "\e[0mConfig path:\e[1;32m\t\t\t$main::config{CONFIG_DIR}\e[0m\n";
- print "\e[0mModule path:\e[1;32m\t\t\t$main::config{MODULE_DIR}\e[0m\n";
- print "\e[0mGCC Version Found:\e[1;32m\t\t$main::config{GCCVER}.$main::config{GCCMINOR}\e[0m\n";
- print "\e[0mCompiler program:\e[1;32m\t\t$main::config{CC}\e[0m\n";
- print "\e[0mGnuTLS Support:\e[1;32m\t\t\t$main::config{USE_GNUTLS}\e[0m\n";
- print "\e[0mOpenSSL Support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n\n";
- print "\e[1;32mImportant note: The maximum length values are now configured in the\e[0m\n";
- print "\e[1;32m configuration file, not in ./configure! See the <limits>\e[0m\n";
- print "\e[1;32m tag in the configuration file for more information.\e[0m\n\n";
-}
+ # Does this line match a directive?
+ if ($line =~ /^\s*%(\w+)\s+(.+)$/) {
+ if ($1 eq 'define') {
+ if ($settings{$2}) {
+ push @lines, "#define $2";
+ } else {
+ push @lines, "#undef $2";
+ }
+ } elsif ($1 eq 'mode') {
+ $mode = oct $2;
+ } elsif ($1 eq 'platform') {
+ push @platforms, $2;
+ } elsif ($1 eq 'target') {
+ push @targets, $2
+ } else {
+ print_warning "unknown template command '$1' in $_!";
+ push @lines, $line;
+ }
+ next;
+ }
+ push @lines, $line;
+ }
+ close $fh;
-sub is_dir
-{
- my ($path) = @_;
- if (chdir($path))
- {
- chdir($main::this);
- return 1;
- }
- else
- {
- # Just in case..
- chdir($main::this);
- return 0;
- }
-}
+ # Only proceed if this file should be templated on this platform.
+ if ($#platforms < 0 || grep { $_ eq $^O } @platforms) {
-sub showhelp
-{
- chomp(my $PWD = `pwd`);
- print <<EOH;
-Usage: configure [options]
-
-*** NOTE: NON-INTERACTIVE CONFIGURE IS *NOT* SUPPORTED BY THE ***
-*** INSPIRCD DEVELOPMENT TEAM. DO NOT ASK FOR HELP REGARDING ***
-*** NON-INTERACTIVE CONFIGURE ON THE FORUMS OR ON IRC! ***
-
-Options: [defaults in brackets after descriptions]
-
-When no options are specified, interactive
-configuration is started and you must specify
-any required values manually. If one or more
-options are specified, non-interactive configuration
-is started, and any omitted values are defaulted.
-
-Arguments with a single \"-\" symbol, as in
-InspIRCd 1.0.x, are also allowed.
-
- --disable-interactive Sets no options itself, but
- will disable any interactive prompting.
- --update Update makefiles and dependencies
- --clean Remove .config.cache file and go interactive
- --enable-gnutls Enable GnuTLS module [no]
- --enable-openssl Enable OpenSSL module [no]
- --enable-epoll Enable epoll() where supported [set]
- --enable-kqueue Enable kqueue() where supported [set]
- --disable-epoll Do not enable epoll(), fall back
- to select() [not set]
- --disable-kqueue Do not enable kqueue(), fall back
- to select() [not set]
- --with-cc=[filename] Use an alternative compiler to
- build InspIRCd [g++]
- --with-maxbuf=[n] Change the per message buffer size [512]
- DO NOT ALTER THIS OPTION WITHOUT GOOD REASON
- AS IT *WILL* BREAK CLIENTS!!!
- --prefix=[directory] Base directory to install into (if defined,
- can automatically define config, module, bin
- and library dirs as subdirectories of prefix)
- [$PWD]
- --config-dir=[directory] Config file directory for config and SSL certs
- [$PWD/run/conf]
- --log-dir=[directory] Log file directory for logs
- [$PWD/run/logs]
- --data-dir=[directory] Data directory for variable data, such as the
- permchannel configuration and the XLine database
- [$PWD/run/data]
- --module-dir=[directory] Modules directory for loadable modules
- [$PWD/run/modules]
- --binary-dir=[directory] Binaries directory for core binary
- [$PWD/run/bin]
- --list-extras Show current status of extra modules
- --enable-extras=[extras] Enable the specified list of extras
- --disable-extras=[extras] Disable the specified list of extras
- --help Show this help text and exit
+ # Add a default target if the template has not defined one.
+ unless (@targets) {
+ push @targets, catfile(CONFIGURE_DIRECTORY, basename $_);
+ }
-EOH
- exit(0);
+ # Write the templated files to disk.
+ for my $target (@targets) {
+
+ # Create the directory if it doesn't already exist.
+ my $directory = dirname $target;
+ unless (-e $directory) {
+ print_format "Creating <|GREEN $directory|> ...\n";
+ create_directory $directory, 0750 or print_error "unable to create $directory: $!";
+ };
+
+ # Write the template file.
+ print_format "Writing <|GREEN $target|> ...\n";
+ open(my $fh, '>', $target) or print_error "unable to write $target: $!";
+ foreach (@lines) {
+ say $fh $_;
+ }
+ close $fh;
+
+ # Set file permissions.
+ if (defined $mode) {
+ chmod $mode, $target;
+ }
+ }
+ }
+ }
}
1;
-
diff --git a/make/console.pm b/make/console.pm
new file mode 100644
index 000000000..132544caa
--- /dev/null
+++ b/make/console.pm
@@ -0,0 +1,163 @@
+#
+# InspIRCd -- Internet Relay Chat Daemon
+#
+# Copyright (C) 2014-2017 Peter Powell <petpow@saberuk.com>
+#
+# This file is part of InspIRCd. InspIRCd is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+package make::console;
+
+BEGIN {
+ require 5.10.0;
+}
+
+use feature ':5.10';
+use strict;
+use warnings FATAL => qw(all);
+
+use Class::Struct qw(struct);
+use Exporter qw(import);
+use File::Path qw(mkpath);
+use File::Spec::Functions qw(rel2abs);
+
+our @EXPORT = qw(command
+ execute_command
+ print_format
+ print_error
+ print_warning
+ prompt_bool
+ prompt_dir
+ prompt_string);
+
+my %FORMAT_CODES = (
+ DEFAULT => "\e[0m",
+ BOLD => "\e[1m",
+ UNDERLINE => "\e[4m",
+
+ RED => "\e[1;31m",
+ GREEN => "\e[1;32m",
+ YELLOW => "\e[1;33m",
+ BLUE => "\e[1;34m"
+);
+
+my %commands;
+
+struct 'command' => {
+ 'callback' => '$',
+ 'description' => '$',
+};
+
+sub __console_format($$) {
+ my ($name, $data) = @_;
+ return $data unless -t STDOUT;
+ return $FORMAT_CODES{uc $name} . $data . $FORMAT_CODES{DEFAULT};
+}
+
+sub print_format($;$) {
+ my $message = shift;
+ my $stream = shift // *STDOUT;
+ while ($message =~ /(<\|(\S+)\s(.*?)\|>)/) {
+ my $formatted = __console_format $2, $3;
+ $message =~ s/\Q$1\E/$formatted/;
+ }
+ print { $stream } $message;
+}
+
+sub print_error {
+ print_format "<|RED Error:|> ", *STDERR;
+ for my $line (@_) {
+ print_format "$line\n", *STDERR;
+ }
+ exit 1;
+}
+
+sub print_warning {
+ print_format "<|YELLOW Warning:|> ", *STDERR;
+ for my $line (@_) {
+ print_format "$line\n", *STDERR;
+ }
+}
+
+sub prompt_bool($$$) {
+ my ($interactive, $question, $default) = @_;
+ while (1) {
+ my $answer = prompt_string($interactive, $question, $default ? 'yes' : 'no');
+ return 1 if $answer =~ /^y(?:es)?$/i;
+ return 0 if $answer =~ /^no?$/i;
+ print_warning "\"$answer\" is not \"yes\" or \"no\". Please try again.\n";
+ }
+}
+
+sub prompt_dir($$$;$) {
+ my ($interactive, $question, $default, $create_now) = @_;
+ my ($answer, $create);
+ do {
+ $answer = rel2abs(prompt_string($interactive, $question, $default));
+ $create = prompt_bool($interactive && !-d $answer, "$answer does not exist. Create it?", 'y');
+ if ($create && $create_now) {
+ unless (create_directory $answer, 0750) {
+ print_warning "unable to create $answer: $!\n";
+ $create = 0;
+ }
+ }
+ } while (!$create);
+ return $answer;
+}
+
+sub prompt_string($$$) {
+ my ($interactive, $question, $default) = @_;
+ return $default unless $interactive;
+ print_format "$question\n";
+ print_format "[<|GREEN $default|>] => ";
+ chomp(my $answer = <STDIN>);
+ say '';
+ return $answer ? $answer : $default;
+}
+
+sub command($$$) {
+ my ($name, $description, $callback) = @_;
+ $commands{$name} = command->new;
+ $commands{$name}->callback($callback);
+ $commands{$name}->description($description);
+}
+
+sub command_alias($$) {
+ my ($source, $target) = @_;
+ command $source, undef, sub(@) {
+ execute_command $target, @_;
+ };
+}
+
+sub execute_command(@) {
+ my $command = defined $_[0] ? lc shift : 'help';
+ if ($command eq 'help') {
+ print_format "<|GREEN Usage:|> $0 <<|UNDERLINE COMMAND|>> [<|UNDERLINE OPTIONS...|>]\n\n";
+ print_format "<|GREEN Commands:|>\n";
+ for my $key (sort keys %commands) {
+ next unless defined $commands{$key}->description;
+ my $name = sprintf "%-15s", $key;
+ my $description = $commands{$key}->description;
+ print_format " <|BOLD $name|> # $description\n";
+ }
+ exit 0;
+ } elsif (!$commands{$command}) {
+ print_error "no command called <|BOLD $command|> exists!",
+ "See <|BOLD $0 help|> for a list of commands.";
+ } else {
+ return $commands{$command}->callback->(@_);
+ }
+}
+
+1;
diff --git a/make/directive.pm b/make/directive.pm
new file mode 100644
index 000000000..c0c2aee85
--- /dev/null
+++ b/make/directive.pm
@@ -0,0 +1,309 @@
+#
+# InspIRCd -- Internet Relay Chat Daemon
+#
+# Copyright (C) 2016 Peter Powell <petpow@saberuk.com>
+#
+# This file is part of InspIRCd. InspIRCd is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+package make::directive;
+
+BEGIN {
+ require 5.10.0;
+}
+
+use feature ':5.10';
+use strict;
+use warnings FATAL => qw(all);
+
+use File::Basename qw(basename dirname);
+use File::Spec::Functions qw(catdir);
+use Exporter qw(import);
+
+use make::configure;
+use make::console;
+
+use constant DIRECTIVE_ERROR_PIPE => $ENV{INSPIRCD_VERBOSE} ? '' : '2>/dev/null';
+use constant VENDOR_DIRECTORY => catdir(dirname(dirname(__FILE__)), 'vendor');
+
+our @EXPORT = qw(get_directive
+ execute_functions);
+
+sub get_directive($$;$)
+{
+ my ($file, $property, $default) = @_;
+ open(my $fh, $file) or return $default;
+
+ my $value = '';
+ while (<$fh>) {
+ if ($_ =~ /^\/\* \$(\S+): (.+) \*\/$/ || $_ =~ /^\/\/\/ \$(\S+): (.+)/) {
+ next unless $1 eq $property;
+ $value .= ' ' . execute_functions($file, $1, $2);
+ }
+ }
+ close $fh;
+
+ # Strip all extraneous whitespace.
+ $value =~ s/^\s+|\s+$//g;
+ return $value || $default;
+}
+
+sub execute_functions($$$) {
+ my ($file, $name, $line) = @_;
+
+ # NOTE: we have to use 'our' instead of 'my' here because of a Perl bug.
+ for (our @parameters = (); $line =~ /([a-z_]+)\((?:\s*"([^"]*)(?{push @parameters, $2})"\s*)*\)/; undef @parameters) {
+ my $sub = make::directive->can("__function_$1");
+ print_error "unknown $name directive '$1' in $file!" unless $sub;
+
+ # Call the subroutine and replace the function.
+ my $result = $sub->($file, @parameters);
+ if (defined $result) {
+ $line = $` . $result . $';
+ next;
+ }
+
+ # If the subroutine returns undef then it is a sign that we should
+ # disregard the rest of the line and stop processing it.
+ $line = $`;
+ }
+
+ return $line;
+}
+
+sub __environment {
+ my ($prefix, $suffix) = @_;
+ $suffix =~ s/[-.]/_/g;
+ $suffix =~ s/[^A-Za-z0-9_]//g;
+ return $prefix . uc $suffix;
+}
+
+sub __error {
+ my ($file, @message) = @_;
+ push @message, '';
+
+ # If we have package details then suggest to the user that they check
+ # that they have the packages installed.=
+ my $dependencies = get_directive($file, 'PackageInfo');
+ if (defined $dependencies) {
+ my @packages = sort grep { /^\S+$/ } split /\s/, $dependencies;
+ push @message, 'You should make sure you have the following packages installed:';
+ for (@packages) {
+ push @message, " * $_";
+ }
+ } else {
+ push @message, 'You should make sure that you have all of the required dependencies';
+ push @message, 'for this module installed.';
+ }
+ push @message, '';
+
+ # If we have author information then tell the user to report the bug
+ # to them. Otherwise, assume it is a bundled module and tell the user
+ # to report it to the InspIRCd issue tracker.
+ my $author = get_directive($file, 'ModAuthor');
+ if (defined $author) {
+ push @message, 'If you believe this error to be a bug then you can try to contact the';
+ push @message, 'author of this module:';
+ my $author_mail = get_directive($file, 'ModAuthorMail');
+ if (defined $author_mail) {
+ push @message, " * $author <$author_mail>";
+ } else {
+ push @message, " * $author";
+ }
+ } else {
+ push @message, 'If you believe this error to be a bug then you can file a bug report';
+ push @message, 'at https://github.com/inspircd/inspircd/issues';
+ }
+ push @message, '';
+
+ push @message, 'If you would like help with fixing this problem then visit our IRC';
+ push @message, 'channel at irc.inspircd.org #InspIRCd for support.';
+ push @message, '';
+
+ print_error @message;
+}
+
+sub __function_error {
+ my ($file, @messages) = @_;
+ __error $file, @messages;
+}
+
+sub __function_execute {
+ my ($file, $command, $environment, $defaults) = @_;
+
+ # Try to execute the command...
+ chomp(my $result = `$command ${\DIRECTIVE_ERROR_PIPE}`);
+ unless ($?) {
+ print_format "Execution of `<|GREEN $command|>` succeeded: <|BOLD $result|>\n";
+ return $result;
+ }
+
+ # If looking up with pkg-config fails then check the environment...
+ if (defined $environment && $environment ne '') {
+ $environment = __environment 'INSPIRCD_', $environment;
+ if (defined $ENV{$environment}) {
+ print_format "Execution of `<|GREEN $command|>` failed; using the environment: <|BOLD $ENV{$environment}|>\n";
+ return $ENV{$environment};
+ }
+ }
+
+ # If all else fails then look for the defaults..
+ if (defined $defaults) {
+ print_format "Execution of `<|GREEN $command|>` failed; using the defaults: <|BOLD $defaults|>\n";
+ return $defaults;
+ }
+
+ # Executing the command failed and we don't have any defaults so give up.
+ __error $file, "`<|GREEN $command|>` exited with a non-zero exit code!";
+}
+
+sub __function_find_compiler_flags {
+ my ($file, $name, $defaults) = @_;
+
+ # Try to look up the compiler flags with pkg-config...
+ chomp(my $flags = `pkg-config --cflags $name ${\DIRECTIVE_ERROR_PIPE}`);
+ unless ($?) {
+ print_format "Found the <|GREEN $name|> compiler flags for <|GREEN ${\basename $file, '.cpp'}|> using pkg-config: <|BOLD $flags|>\n";
+ return $flags;
+ }
+
+ # If looking up with pkg-config fails then check the environment...
+ my $key = __environment 'INSPIRCD_CXXFLAGS_', $name;
+ if (defined $ENV{$key}) {
+ print_format "Found the <|GREEN $name|> compiler flags for <|GREEN ${\basename $file, '.cpp'}|> using the environment: <|BOLD $ENV{$key}|>\n";
+ return $ENV{$key};
+ }
+
+ # If all else fails then look for the defaults..
+ if (defined $defaults) {
+ print_format "Using the default <|GREEN $name|> compiler flags for <|GREEN ${\basename $file, '.cpp'}|>: <|BOLD $defaults|>\n";
+ return $defaults;
+ }
+
+ # We can't find it via pkg-config, via the environment, or via the defaults so give up.
+ __error $file, "unable to find the <|GREEN $name|> compiler flags for <|GREEN ${\basename $file, '.cpp'}|>!";
+}
+
+sub __function_find_linker_flags {
+ my ($file, $name, $defaults) = @_;
+
+ # Try to look up the linker flags with pkg-config...
+ chomp(my $flags = `pkg-config --libs $name ${\DIRECTIVE_ERROR_PIPE}`);
+ unless ($?) {
+ print_format "Found the <|GREEN $name|> linker flags for <|GREEN ${\basename $file, '.cpp'}|> using pkg-config: <|BOLD $flags|>\n";
+ return $flags;
+ }
+
+ # If looking up with pkg-config fails then check the environment...
+ my $key = __environment 'INSPIRCD_CXXFLAGS_', $name;
+ if (defined $ENV{$key}) {
+ print_format "Found the <|GREEN $name|> linker flags for <|GREEN ${\basename $file, '.cpp'}|> using the environment: <|BOLD $ENV{$key}|>\n";
+ return $ENV{$key};
+ }
+
+ # If all else fails then look for the defaults..
+ if (defined $defaults) {
+ print_format "Using the default <|GREEN $name|> linker flags for <|GREEN ${\basename $file, '.cpp'}|>: <|BOLD $defaults|>\n";
+ return $defaults;
+ }
+
+ # We can't find it via pkg-config, via the environment, or via the defaults so give up.
+ __error $file, "unable to find the <|GREEN $name|> linker flags for <|GREEN ${\basename $file, '.cpp'}|>!";
+}
+
+sub __function_require_compiler {
+ my ($file, $name, $minimum, $maximum) = @_;
+
+ # Look up information about the compiler.
+ return undef unless $ENV{CXX};
+ my %compiler = get_compiler_info($ENV{CXX});
+
+ # Check whether the current compiler is suitable.
+ return undef unless $compiler{NAME} eq $name;
+ return undef if defined $minimum && $compiler{VERSION} < $minimum;
+ return undef if defined $maximum && $compiler{VERSION} > $maximum;
+
+ # Requirement directives don't change anything directly.
+ return "";
+}
+
+sub __function_require_system {
+ my ($file, $name, $minimum, $maximum) = @_;
+ my ($system, $version);
+
+ # Linux is special and can be compared by distribution names.
+ if ($^O eq 'linux' && $name ne 'linux') {
+ chomp($system = lc `lsb_release --id --short 2>/dev/null`);
+ chomp($version = lc `lsb_release --release --short 2>/dev/null`);
+ }
+
+ # Gather information on the system if we don't have it already.
+ chomp($system ||= lc `uname -s 2>/dev/null`);
+ chomp($version ||= lc `uname -r 2>/dev/null`);
+
+ # We only care about the important bit of the version number so trim the rest.
+ $version =~ s/^(\d+\.\d+).+/$1/;
+
+ # Check whether the current system is suitable.
+ return undef if $name ne $system;
+ return undef if defined $minimum && $version < $minimum;
+ return undef if defined $maximum && $version > $maximum;
+
+ # Requirement directives don't change anything directly.
+ return "";
+}
+
+sub __function_require_version {
+ my ($file, $name, $minimum, $maximum) = @_;
+
+ # If pkg-config isn't installed then we can't do anything here.
+ if (system "pkg-config --exists $name ${\DIRECTIVE_ERROR_PIPE}") {
+ print_warning "unable to look up the version of <|GREEN $name|> using pkg-config!";
+ return undef;
+ }
+
+ # Check with pkg-config whether we have the required version.
+ return undef if defined $minimum && system "pkg-config --atleast-version $minimum $name";
+ return undef if defined $maximum && system "pkg-config --max-version $maximum $name";
+
+ # Requirement directives don't change anything directly.
+ return "";
+}
+
+sub __function_vendor_directory {
+ my ($file, $name) = @_;
+
+ # Try to look the directory up in the environment...
+ my $key = __environment 'INSPIRCD_VENDOR_', $name;
+ if (defined $ENV{$key}) {
+ print_format "Found the <|GREEN $name|> vendor directory for <|GREEN ${\basename $file, '.cpp'}|> using the environment: <|BOLD $ENV{$key}|>\n";
+ return $ENV{$key};
+ }
+
+ my $directory = catdir(VENDOR_DIRECTORY, $name);
+ if (-d $directory) {
+ print_format "Using the default <|GREEN $name|> vendor directory for <|GREEN ${\basename $file, '.cpp'}|>: <|BOLD $directory|>\n";
+ return $directory;
+ }
+
+ # We can't find it via the environment or via the filesystem so give up.
+ __error $file, "unable to find the <|GREEN $name|> vendor directory for <|GREEN ${\basename $file, '.cpp'}|>!";
+}
+
+sub __function_warning {
+ my ($file, @messages) = @_;
+ print_warning @messages;
+}
+
+1;
diff --git a/make/gnutlscert.pm b/make/gnutlscert.pm
deleted file mode 100644
index 2c46e0e63..000000000
--- a/make/gnutlscert.pm
+++ /dev/null
@@ -1,150 +0,0 @@
-#
-# InspIRCd -- Internet Relay Chat Daemon
-#
-# Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
-# Copyright (C) 2007 Craig Edwards <craigedwards@brainbox.cc>
-#
-# This file is part of InspIRCd. InspIRCd is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-
-package make::gnutlscert;
-
-require 5.8.0;
-
-use strict;
-use warnings FATAL => qw(all);
-
-use Exporter 'import';
-use make::configure;
-our @EXPORT = qw(make_gnutls_cert);
-
-# On OS X the GnuTLS certtool is prefixed to avoid collision with the system certtool.
-my $certtool = $^O eq 'darwin' ? 'gnutls-certtool' : 'certtool';
-
-sub make_gnutls_cert()
-{
- if (system "$certtool --version >/dev/null 2>&1")
- {
- print "\e[1;31mError:\e[0m unable to find '$certtool' in the PATH!\n";
- return 1;
- }
- open (FH, ">certtool.template");
- my $timestr = time();
- my $commonname = promptstring_s('What is the hostname of your server?', 'irc.example.com');
- my $email = promptstring_s('What email address can you be contacted at?', 'example@example.com');
- my $unit = promptstring_s('What is the name of your unit?', 'Server Admins');
- my $org = promptstring_s('What is the name of your organization?', 'Example IRC Network');
- my $city = promptstring_s('What city are you located in?', 'Example City');
- my $state = promptstring_s('What state are you located in?', 'Example State');
- my $country = promptstring_s('What is the ISO 3166-1 code for the country you are located in?', 'XZ');
- my $days = promptstring_s('How many days do you want your certificate to be valid for?', '365');
- print FH <<__END__;
-# X.509 Certificate options
-#
-# DN options
-
-# The organization of the subject.
-organization = "$org"
-
-# The organizational unit of the subject.
-unit = "$unit"
-
-# The locality of the subject.
-locality = "$city"
-
-# The state of the certificate owner.
-state = "$state"
-
-# The country of the subject. Two letter code.
-country = "$country"
-
-# The common name of the certificate owner.
-cn = "$commonname"
-
-# A user id of the certificate owner.
-#uid = "clauper"
-
-# If the supported DN OIDs are not adequate you can set
-# any OID here.
-# For example set the X.520 Title and the X.520 Pseudonym
-# by using OID and string pairs.
-#dn_oid = "2.5.4.12" "Dr." "2.5.4.65" "jackal"
-
-# This is deprecated and should not be used in new
-# certificates.
-# pkcs9_email = "none\@none.org"
-
-# The serial number of the certificate
-serial = $timestr
-
-# In how many days, counting from today, this certificate will expire.
-expiration_days = $days
-
-# X.509 v3 extensions
-
-# A dnsname in case of a WWW server.
-#dns_name = "www.none.org"
-
-# An IP address in case of a server.
-#ip_address = "192.168.1.1"
-
-# An email in case of a person
-email = "$email"
-
-# An URL that has CRLs (certificate revocation lists)
-# available. Needed in CA certificates.
-#crl_dist_points = "http://www.getcrl.crl/getcrl/"
-
-# Whether this is a CA certificate or not
-#ca
-
-# Whether this certificate will be used for a TLS client
-tls_www_client
-
-# Whether this certificate will be used for a TLS server
-tls_www_server
-
-# Whether this certificate will be used to sign data (needed
-# in TLS DHE ciphersuites).
-signing_key
-
-# Whether this certificate will be used to encrypt data (needed
-# in TLS RSA ciphersuites). Note that it is prefered to use different
-# keys for encryption and signing.
-encryption_key
-
-# Whether this key will be used to sign other certificates.
-cert_signing_key
-
-# Whether this key will be used to sign CRLs.
-crl_signing_key
-
-# Whether this key will be used to sign code.
-code_signing_key
-
-# Whether this key will be used to sign OCSP data.
-ocsp_signing_key
-
-# Whether this key will be used for time stamping.
-time_stamping_key
-__END__
-close(FH);
-if ( (my $status = system("$certtool --generate-privkey --outfile key.pem")) ne 0) { return 1; }
-if ( (my $status = system("$certtool --generate-self-signed --load-privkey key.pem --outfile cert.pem --template certtool.template")) ne 0) { return 1; }
-unlink("certtool.template");
-return 0;
-}
-
-1;
-
diff --git a/make/opensslcert.pm b/make/opensslcert.pm
deleted file mode 100644
index 20da704f7..000000000
--- a/make/opensslcert.pm
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# InspIRCd -- Internet Relay Chat Daemon
-#
-# Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
-# Copyright (C) 2007 Craig Edwards <craigedwards@brainbox.cc>
-#
-# This file is part of InspIRCd. InspIRCd is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-
-package make::opensslcert;
-
-require 5.8.0;
-
-use strict;
-use warnings FATAL => qw(all);
-
-use Exporter 'import';
-use make::configure;
-our @EXPORT = qw(make_openssl_cert);
-
-
-sub make_openssl_cert()
-{
- if (system 'openssl version >/dev/null 2>&1')
- {
- print "\e[1;31mCertificate generation failed:\e[0m unable to find 'openssl' in the PATH!\n";
- return;
- }
- open (FH, ">openssl.template");
- my $commonname = promptstring_s('What is the hostname of your server?', 'irc.example.com');
- my $email = promptstring_s('What email address can you be contacted at?', 'example@example.com');
- my $unit = promptstring_s('What is the name of your unit?', 'Server Admins');
- my $org = promptstring_s('What is the name of your organization?', 'Example IRC Network');
- my $city = promptstring_s('What city are you located in?', 'Example City');
- my $state = promptstring_s('What state are you located in?', 'Example State');
- my $country = promptstring_s('What is the ISO 3166-1 code for the country you are located in?', 'XZ');
- my $time = promptstring_s('How many days do you want your certificate to be valid for?', '365');
- my $use_1024 = promptstring_s('Do you want to generate less secure dhparams which are compatible with old versions of Java?', 'n');
- print FH <<__END__;
-$country
-$state
-$city
-$org
-$unit
-$commonname
-$email
-__END__
-close(FH);
-my $dhbits = $use_1024 =~ /^(1|on|true|yes|y)$/ ? 1024 : 2048;
-system("cat openssl.template | openssl req -x509 -nodes -newkey rsa:2048 -keyout key.pem -out cert.pem -days $time 2>/dev/null");
-system("openssl dhparam -out dhparams.pem $dhbits");
-unlink("openssl.template");
-}
-
-1;
diff --git a/make/run-cc.pl b/make/run-cc.pl
deleted file mode 100755
index 58b5850ca..000000000
--- a/make/run-cc.pl
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/env perl
-
-#
-# InspIRCd -- Internet Relay Chat Daemon
-#
-# Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
-# Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
-#
-# This file is part of InspIRCd. InspIRCd is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-
-### THIS IS DESIGNED TO BE RUN BY MAKE! DO NOT RUN FROM THE SHELL (because it MIGHT sigterm the shell)! ###
-
-use strict;
-use warnings FATAL => qw(all);
-
-use POSIX ();
-
-# Runs the compiler, passing it the given arguments.
-# Filters select output from the compiler's standard error channel and
-# can take different actions as a result.
-
-# NOTE: this is *NOT* a hash (sadly: a hash would stringize all the regexes and thus render them useless, plus you can't index a hash based on regexes anyway)
-# even though we use the => in it.
-
-# The subs are passed the message, and anything the regex captured.
-
-my $cc = shift(@ARGV);
-
-my $showncmdline = 0;
-
-# GCC's "location of error stuff", which accumulates the "In file included from" include stack
-my $location = "";
-
-my @msgfilters = (
- [ qr/^(.*) warning: cannot pass objects of non-POD type `(.*)' through `\.\.\.'; call will abort at runtime/ => sub {
- my ($msg, $where, $type) = @_;
- my $errstr = $location . "$where error: cannot pass objects of non-POD type `$type' through `...'\n";
- $location = "";
- if ($type =~ m/::(basic_)?string/) {
- $errstr .= "$where (Did you forget to call c_str()?)\n";
- }
- die $errstr;
- } ],
-
- # Start of an include stack.
- [ qr/^In file included from .*[,:]$/ => sub {
- my ($msg) = @_;
- $location = "$msg\n";
- return undef;
- } ],
-
- # Continuation of an include stack.
- [ qr/^ from .*[,:]$/ => sub {
- my ($msg) = @_;
- $location .= "$msg\n";
- return undef;
- } ],
-
- # A function, method, constructor, or destructor is the site of a problem
- [ qr/In ((con|de)structor|(member )?function)/ => sub {
- my ($msg) = @_;
- # If a complete location string is waiting then probably we dropped an error, so drop the location for a new one.
- if ($location =~ m/In ((con|de)structor|(member )?function)/) {
- $location = "$msg\n";
- } else {
- $location .= "$msg\n";
- }
- return undef;
- } ],
-
- [ qr/^.* warning: / => sub {
- my ($msg) = @_;
- my $str = $location . "\e[33;1m$msg\e[0m\n";
- $showncmdline = 1;
- $location = "";
- return $str;
- } ],
-
- [ qr/^.* error: / => sub {
- my ($msg) = @_;
- my $str = "";
- $str = "An error occured when executing:\e[37;1m $cc " . join(' ', @ARGV) . "\n" unless $showncmdline;
- $showncmdline = 1;
- $str .= $location . "\e[31;1m$msg\e[0m\n";
- $location = "";
- return $str;
- } ],
-
- [ qr/./ => sub {
- my ($msg) = @_;
- $msg = $location . $msg;
- $location = "";
- $msg =~ s/std::basic_string\<char\, std\:\:char_traits\<char\>, std::allocator\<char\> \>(\s+|)/std::string/g;
- $msg =~ s/std::basic_string\<char\, .*?irc_char_traits\<char\>, std::allocator\<char\> \>(\s+|)/irc::string/g;
- for my $stl (qw(deque vector list)) {
- $msg =~ s/std::$stl\<(\S+), std::allocator\<\1\> \>/std::$stl\<$1\>/g;
- $msg =~ s/std::$stl\<(std::pair\<\S+, \S+\>), std::allocator\<\1 \> \>/std::$stl<$1 >/g;
- }
- $msg =~ s/std::map\<(\S+), (\S+), std::less\<\1\>, std::allocator\<std::pair\<const \1, \2\> \> \>/std::map<$1, $2>/g;
- # Warning: These filters are GNU C++ specific!
- $msg =~ s/__gnu_cxx::__normal_iterator\<(\S+)\*, std::vector\<\1\> \>/std::vector<$1>::iterator/g;
- $msg =~ s/__gnu_cxx::__normal_iterator\<(std::pair\<\S+, \S+\>)\*, std::vector\<\1 \> \>/std::vector<$1 >::iterator/g;
- $msg =~ s/__gnu_cxx::__normal_iterator\<char\*, std::string\>/std::string::iterator/g;
- $msg =~ s/__gnu_cxx::__normal_iterator\<char\*, irc::string\>/irc::string::iterator/g;
- return $msg;
- } ],
-);
-
-my $pid;
-
-my ($r_stderr, $w_stderr);
-
-my $name = "";
-my $action = "";
-
-if ($cc eq "ar") {
- $name = $ARGV[1];
- $action = "ARCHIVE";
-} else {
- foreach my $n (@ARGV)
- {
- if ($n =~ /\.cpp$/)
- {
- my $f = $n;
- if (defined $ENV{SOURCEPATH}) {
- $f =~ s#^$ENV{SOURCEPATH}/src/##;
- }
- if ($action eq "BUILD")
- {
- $name .= " " . $f;
- }
- else
- {
- $action = "BUILD";
- $name = $f;
- }
- }
- elsif ($action eq "BUILD") # .cpp has priority.
- {
- next;
- }
- elsif ($n eq "-o")
- {
- $action = $name = $n;
- }
- elsif ($name eq "-o")
- {
- $action = "LINK";
- $name = $n;
- }
- }
-}
-
-if (!defined($cc) || $cc eq "") {
- die "Compiler not specified!\n";
-}
-
-pipe($r_stderr, $w_stderr) or die "pipe stderr: $!\n";
-
-$pid = fork;
-
-die "Cannot fork to start $cc! $!\n" unless defined($pid);
-
-if ($pid) {
-
- printf "\t\e[1;32m%-20s\e[0m%s\n", $action . ":", $name unless $name eq "";
-
- my $fail = 0;
- # Parent - Close child-side pipes.
- close $w_stderr;
- # Close STDIN to ensure no conflicts with child.
- close STDIN;
- # Now read each line of stderr
-LINE: while (defined(my $line = <$r_stderr>)) {
- chomp $line;
-
- for my $filter (@msgfilters) {
- my @caps;
- if (@caps = ($line =~ $filter->[0])) {
- $@ = "";
- $line = eval {
- $filter->[1]->($line, @caps);
- };
- if ($@) {
- # Note that $line is undef now.
- $fail = 1;
- print STDERR $@;
- }
- next LINE unless defined($line);
- }
- }
- # Chomp off newlines again, in case the filters put some back in.
- chomp $line;
- print STDERR "$line\n";
- }
- waitpid $pid, 0;
- close $r_stderr;
- my $exit = $?;
- # Simulate the same exit, so make gets the right termination info.
- if (POSIX::WIFSIGNALED($exit)) {
- # Make won't get the right termination info (it gets ours, not the compiler's), so we must tell the user what really happened ourselves!
- print STDERR "$cc killed by signal " . POSIX::WTERMSIGN($exit) . "\n";
- kill "TERM", getppid(); # Needed for bsd make.
- kill "TERM", $$;
- }
- else {
- if (POSIX::WEXITSTATUS($exit) == 0) {
- if ($fail) {
- kill "TERM", getppid(); # Needed for bsd make.
- kill "TERM", $$;
- }
- exit 0;
- } else {
- exit POSIX::WEXITSTATUS($exit);
- }
- }
-} else {
- # Child - Close parent-side pipes.
- close $r_stderr;
- # Divert stderr
- open STDERR, ">&", $w_stderr or die "Cannot divert STDERR: $!\n";
- # Run the compiler!
- exec { $cc } $cc, @ARGV;
- die "exec $cc: $!\n";
-}
diff --git a/make/template/bsd.mk b/make/template/bsd.mk
new file mode 100644
index 000000000..05d413d0a
--- /dev/null
+++ b/make/template/bsd.mk
@@ -0,0 +1,33 @@
+%platform darwin
+%platform freebsd
+%platform netbsd
+%platform openbsd
+%target Makefile
+#
+# InspIRCd -- Internet Relay Chat Daemon
+#
+# Copyright (C) 2017 Peter Powell <petpow@saberuk.com>
+#
+# This file is part of InspIRCd. InspIRCd is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# This file will be installed as `Makefile` on BSD derivatives. When a user runs
+# BSD Make it will be picked up as the default makefile even on systems like
+# OpenBSD which have removed BSDMakefile support. If they run GNU Make then it
+# will ignore this file and run GNUmakefile instead.
+
+all clean configureclean debug deinstall distclean help install:
+ @echo "InspIRCd no longer supports BSD Make. You should install GNU Make instead."
+ @echo "If this is problematic for you then please contact us via our IRC channel"
+ @echo "at irc.inspircd.org #InspIRCd."
+ @exit 1
diff --git a/make/check_strlcpy.cpp b/make/template/config.h
index e51d18d40..2fbf5c564 100644
--- a/make/check_strlcpy.cpp
+++ b/make/template/config.h
@@ -1,7 +1,7 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
- * Copyright (C) 2015 Peter Powell <petpow@saberuk.com>
+ * Copyright (C) 2014 Peter Powell <petpow@saberuk.com>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
@@ -17,9 +17,19 @@
*/
-#include <string.h>
+#pragma once
-int main() {
- char test[5];
- strlcpy(test, "test", sizeof(test));
-}
+#define INSPIRCD_BRANCH "InspIRCd-@VERSION_MAJOR@"
+#define INSPIRCD_VERSION "InspIRCd-@VERSION_FULL@"
+
+#define INSPIRCD_CONFIG_PATH "@CONFIG_DIR@"
+#define INSPIRCD_DATA_PATH "@DATA_DIR@"
+#define INSPIRCD_LOG_PATH "@LOG_DIR@"
+#define INSPIRCD_MODULE_PATH "@MODULE_DIR@"
+
+#ifndef _WIN32
+ %target include/config.h
+ %define HAS_ARC4RANDOM_BUF
+ %define HAS_CLOCK_GETTIME
+ %define HAS_EVENTFD
+#endif
diff --git a/make/template/gdbargs b/make/template/gdbargs
new file mode 100644
index 000000000..de76c7270
--- /dev/null
+++ b/make/template/gdbargs
@@ -0,0 +1,4 @@
+%target .gdbargs
+handle SIGPIPE pass nostop noprint
+handle SIGHUP pass nostop noprint
+run
diff --git a/make/template/inspircd b/make/template/inspircd
index b43ad60c9..91b269412 100644
--- a/make/template/inspircd
+++ b/make/template/inspircd
@@ -1,3 +1,4 @@
+%mode 0750
#!/usr/bin/env perl
#
@@ -29,17 +30,36 @@ use strict;
use POSIX;
use Fcntl;
+# From http://refspecs.linuxbase.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
+use constant {
+ STATUS_EXIT_SUCCESS => 0,
+ STATUS_EXIT_DEAD_WITH_PIDFILE => 1,
+ STATUS_EXIT_DEAD_WITH_LOCKFILE => 2,
+ STATUS_EXIT_NOT_RUNNING => 3,
+ STATUS_EXIT_UNKNOWN => 4,
+
+ GENERIC_EXIT_SUCCESS => 0,
+ GENERIC_EXIT_UNSPECIFIED => 1,
+ GENERIC_EXIT_INVALID_ARGUMENTS => 2,
+ GENERIC_EXIT_UNIMPLEMENTED => 3,
+ GENERIC_EXIT_INSUFFICIENT_PRIVILEGE => 4,
+ GENERIC_EXIT_NOT_INSTALLED => 5,
+ GENERIC_EXIT_NOT_CONFIGURED => 6,
+ GENERIC_EXIT_NOT_RUNNING => 7
+};
+
+my $scriptpath = "@SCRIPT_DIR@";
my $basepath = "@BASE_DIR@";
my $confpath = "@CONFIG_DIR@/";
my $binpath = "@BINARY_DIR@";
my $runpath = "@BASE_DIR@";
my $datadir = "@DATA_DIR@";
my $valgrindlogpath = "$basepath/valgrindlogs";
-my $executable = "@EXECUTABLE@";
-my $version = "@VERSION@";
+my $executable = "inspircd";
+my $version = "@VERSION_FULL@";
my $uid = "@UID@";
-if ($< == 0 || $> == 0) {
+if (!(grep { $_ eq '--runasroot' } @ARGV) && ($< == 0 || $> == 0)) {
if ($uid !~ /^\d+$/) {
# Named UID, look it up
$uid = getpwnam $uid;
@@ -87,12 +107,11 @@ if (!defined($sub))
{
print STDERR "Invalid command or none given.\n";
cmd_help();
- exit 1;
+ exit GENERIC_EXIT_UNIMPLEMENTED;
}
else
{
- $sub->(@ARGV);
- exit 0;
+ exit $sub->(@ARGV); # Error code passed through return value
}
sub cmd_help()
@@ -105,7 +124,7 @@ sub cmd_help()
$_ =~ s/_/-/g foreach (@cmds, @devs);
print STDERR "Usage: ./inspircd (" . join("|", @cmds) . ")\n";
print STDERR "Developer arguments: (" . join("|", @devs) . ")\n";
- exit 0;
+ exit GENERIC_EXIT_SUCCESS;
}
sub cmd_status()
@@ -113,10 +132,10 @@ sub cmd_status()
if (getstatus() == 1) {
my $pid = getprocessid();
print "InspIRCd is running (PID: $pid)\n";
- exit();
+ exit STATUS_EXIT_SUCCESS;
} else {
print "InspIRCd is not running. (Or PID File not found)\n";
- exit();
+ exit STATUS_EXIT_NOT_RUNNING;
}
}
@@ -126,23 +145,23 @@ sub cmd_rehash()
my $pid = getprocessid();
system("kill -HUP $pid >/dev/null 2>&1");
print "InspIRCd rehashed (pid: $pid).\n";
- exit();
+ exit GENERIC_EXIT_SUCCESS;
} else {
print "InspIRCd is not running. (Or PID File not found)\n";
- exit();
+ exit GENERIC_EXIT_NOT_RUNNING;
}
}
sub cmd_cron()
{
if (getstatus() == 0) { goto &cmd_start(@_); }
- exit();
+ exit GENERIC_EXIT_UNSPECIFIED;
}
sub cmd_version()
{
print "InspIRCd version: $version\n";
- exit();
+ exit GENERIC_EXIT_SUCCESS;
}
sub cmd_restart(@)
@@ -156,13 +175,13 @@ sub hid_cheese_sandwich()
{
print "Creating Cheese Sandwich..\n";
print "Done.\n";
- exit();
+ exit GENERIC_EXIT_SUCCESS;
}
sub cmd_start(@)
{
# Check to see its not 'running' already.
- if (getstatus() == 1) { print "InspIRCd is already running.\n"; return 0; }
+ if (getstatus() == 1) { print "InspIRCd is already running.\n"; exit GENERIC_EXIT_SUCCESS; }
# If we are still alive here.. Try starting the IRCd..
chdir $runpath;
print "$binpath/$executable doesn't exist\n" and return 0 unless(-e "$binpath/$executable");
@@ -185,7 +204,7 @@ sub dev_debug(@)
checkgdb();
# If we are still alive here.. Try starting the IRCd..
- exec 'gdb', "--command=$basepath/.gdbargs", '--args', "$binpath/$executable", qw(--nofork --debug), @_;
+ exec 'gdb', "--command=$scriptpath/.gdbargs", '--args', "$binpath/$executable", qw(--nofork --debug), @_;
die "Failed to start GDB: $!\n";
}
@@ -204,7 +223,7 @@ sub dev_screendebug(@)
# If we are still alive here.. Try starting the IRCd..
print "Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the gdb output and get a backtrace.\n";
print "Once you're inside the screen session press ^C + d to re-detach from the session\n";
- exec qw(screen -m -d gdb), "--command=$basepath/.gdbargs", '-args', "$binpath/$executable", qw(--nofork --debug --nolog), @_;
+ exec qw(screen -m -d gdb), "--command=$scriptpath/.gdbargs", '-args', "$binpath/$executable", qw(--nofork --debug --nolog), @_;
die "Failed to start screen: $!\n";
}
@@ -224,7 +243,7 @@ sub dev_valdebug(@)
# If we are still alive here.. Try starting the IRCd..
# May want to do something with these args at some point: --suppressions=.inspircd.sup --gen-suppressions=yes
# Could be useful when we want to stop it complaining about things we're sure aren't issues.
- exec qw(valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=10), "$binpath/$executable", qw(--nofork --debug --nolog), @_;
+ exec qw(valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=30), "$binpath/$executable", qw(--nofork --debug --nolog), @_;
die "Failed to start valgrind: $!\n";
}
@@ -258,7 +277,7 @@ sub dev_valdebug_unattended(@)
sysopen STDERR, "$valgrindlogpath/valdebug.$suffix", O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND, 0666 or die "Can't open $valgrindlogpath/valdebug.$suffix: $!\n";
# May want to do something with these args at some point: --suppressions=.inspircd.sup --gen-suppressions=yes
# Could be useful when we want to stop it complaining about things we're sure aren't issues.
- exec qw(valgrind -v --tool=memcheck --leak-check=full --show-reachable=yes --num-callers=15 --track-fds=yes),
+ exec qw(valgrind -v --tool=memcheck --leak-check=full --show-reachable=yes --num-callers=30 --track-fds=yes),
"--suppressions=$binpath/valgrind.sup", qw(--gen-suppressions=all),
qw(--leak-resolution=med --time-stamp=yes --log-fd=2 --),
"$binpath/$executable", qw(--nofork --debug --nolog), @_;
@@ -283,28 +302,28 @@ sub dev_screenvaldebug(@)
# If we are still alive here.. Try starting the IRCd..
print "Starting InspIRCd in `screen`, type `screen -r` when the ircd crashes to view the valgrind and gdb output and get a backtrace.\n";
print "Once you're inside the screen session press ^C + d to re-detach from the session\n";
- exec qw(screen -m -d valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=10), "$binpath/$executable", qw(--nofork --debug --nolog), @_;
+ exec qw(screen -m -d valgrind -v --tool=memcheck --leak-check=yes --db-attach=yes --num-callers=30), "$binpath/$executable", qw(--nofork --debug --nolog), @_;
die "Failed to start screen: $!\n";
}
sub cmd_stop()
{
- if (getstatus() == 0) { print "InspIRCd is not running. (Or PID File not found)\n"; return 0; }
+ if (getstatus() == 0) { print "InspIRCd is not running. (Or PID File not found)\n"; return GENERIC_EXIT_SUCCESS; }
# Get to here, we have something to kill.
my $pid = getprocessid();
print "Stopping InspIRCd (pid: $pid)...\n";
- my $maxwait = (`ps -o command $pid` =~ /valgrind/i) ? 90 : 15;
+ my $maxwait = (`ps -o command $pid 2>/dev/null` =~ /valgrind/i) ? 90 : 15;
kill TERM => $pid or die "Cannot terminate IRCd: $!\n";
for (1..$maxwait) {
sleep 1;
if (getstatus() == 0) {
print "InspIRCd Stopped.\n";
- return;
+ return GENERIC_EXIT_SUCCESS;
}
}
print "InspIRCd not dying quietly -- forcing kill\n";
kill KILL => $pid;
- return 0;
+ return GENERIC_EXIT_SUCCESS;
}
###
@@ -415,7 +434,7 @@ sub checkvalgrind
unless(`valgrind --version`)
{
print "Couldn't start valgrind: $!\n";
- exit;
+ exit GENERIC_EXIT_UNSPECIFIED;
}
}
@@ -424,7 +443,7 @@ sub checkgdb
unless(`gdb --version`)
{
print "Couldn't start gdb: $!\n";
- exit;
+ exit GENERIC_EXIT_UNSPECIFIED;
}
}
@@ -433,6 +452,6 @@ sub checkscreen
unless(`screen --version`)
{
print "Couldn't start screen: $!\n";
- exit;
+ exit GENERIC_EXIT_UNSPECIFIED;
}
}
diff --git a/make/template/inspircd-genssl.1 b/make/template/inspircd-genssl.1
new file mode 100644
index 000000000..63d65c827
--- /dev/null
+++ b/make/template/inspircd-genssl.1
@@ -0,0 +1,46 @@
+.\"
+.\" InspIRCd -- Internet Relay Chat Daemon
+.\"
+.\" Copyright (C) 2014 Peter Powell <petpow@saberuk.com>
+.\"
+.\" This file is part of InspIRCd. InspIRCd is free software: you can
+.\" redistribute it and/or modify it under the terms of the GNU General Public
+.\" License as published by the Free Software Foundation, version 2.
+.\"
+.\" This program is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+.\" FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+.\" details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.\"
+
+
+.TH "InspIRCd" "1" "June 2014" "InspIRCd @VERSION_FULL@" "InspIRCd Manual"
+
+.SH "NAME"
+\t\fBInspIRCd\fR - \fIthe\fR stable, high-performance and modular Internet Relay Chat Daemon
+.BR
+
+.SH "SYNOPSIS"
+\t\fBinspircd-genssl\fR [ auto | gnutls | openssl ]
+
+.SH "OPTIONS"
+.TP
+.B "auto"
+.br
+Looks for both GnuTLS and OpenSSL and uses the first one which is available for certificate generation.
+.TP
+.B "gnutls"
+.br
+Generates certificates using GnuTLS.
+.TP
+.br
+.B "openssl"
+Generates certificates using OpenSSL.
+
+.SH "SUPPORT"
+IRC support for InspIRCd can be found at ircs://irc.inspircd.org/inspircd.
+
+Bug reports and feature requests can be filed at https://github.com/inspircd/inspircd/issues.
diff --git a/make/template/inspircd.1 b/make/template/inspircd.1
new file mode 100644
index 000000000..2bc8fd044
--- /dev/null
+++ b/make/template/inspircd.1
@@ -0,0 +1,108 @@
+.\"
+.\" InspIRCd -- Internet Relay Chat Daemon
+.\"
+.\" Copyright (C) 2014 Peter Powell <petpow@saberuk.com>
+.\"
+.\" This file is part of InspIRCd. InspIRCd is free software: you can
+.\" redistribute it and/or modify it under the terms of the GNU General Public
+.\" License as published by the Free Software Foundation, version 2.
+.\"
+.\" This program is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+.\" FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+.\" details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program. If not, see <http://www.gnu.org/licenses/>.
+.\"
+
+
+.TH "InspIRCd" "1" "June 2014" "InspIRCd @VERSION_FULL@" "InspIRCd Manual"
+
+.SH "NAME"
+\t\fBInspIRCd\fR - \fIthe\fR stable, high-performance and modular Internet Relay Chat Daemon
+.BR
+
+.SH "SYNOPSIS"
+\t\fBinspircd\fR [--config <file>] [--debug] [--nofork] [--nolog] [--nopid] [--runasroot] [--version]
+
+.SH "OPTIONS"
+.TP
+.B "--config <file>"
+.br
+Sets the path to the main configuration file. Defaults to \fI@CONFIG_DIR@/inspircd.conf\fR.
+.TP
+.B "--debug"
+.br
+Log verbosely to the standard output stream.
+.TP
+.B "--nofork"
+.br
+Don't fork into the background after starting up.
+.TP
+.B "--nolog"
+.br
+Don't write to log files.
+.TP
+.B "--nopid"
+.br
+Don't write to the PID file.
+.TP
+.B "--runasroot"
+.br
+Allow the server to start as root (not recommended).
+.TP
+.B "--version"
+.br
+Displays the InspIRCd version and exits.
+
+.SH "EXIT STATUS"
+.TP
+.B "0 (EXIT_STATUS_NOERROR)"
+.br
+The server exited cleanly.
+.TP
+.B "1 (EXIT_STATUS_DIE)"
+.br
+The server exited because the DIE command was executed.
+.TP
+.B "2 (EXIT_STATUS_CONFIG)"
+.br
+The server exited because of a configuration file error.
+.TP
+.B "3 (EXIT_STATUS_LOG)"
+.br
+The server exited because of a log file error.
+.TP
+.B "4 (EXIT_STATUS_FORK)"
+.br
+The server exited because it was unable to fork into the background.
+.TP
+.B "5 (EXIT_STATUS_ARGV)"
+.br
+The server exited because an invalid argument was passed to it on the command line.
+.TP
+.B "6 (EXIT_STATUS_PID)"
+.br
+The server exited because it was unable to write to the PID file.
+.TP
+.B "7 (EXIT_STATUS_SOCKETENGINE)"
+.br
+The server exited because it was unable to initialize the @SOCKETENGINE@ socket engine.
+.TP
+.B "8 (EXIT_STATUS_ROOT)"
+.br
+The server exited because the user tried to start as root without \fI--runasroot\fR.
+.TP
+.B "9 (EXIT_STATUS_MODULE)"
+.br
+The server exited because it was unable to load a module on first run.
+.TP
+.B "10 (EXIT_STATUS_SIGTERM)"
+.br
+The server exited because it received SIGTERM.
+
+.SH "SUPPORT"
+IRC support for InspIRCd can be found at ircs://irc.inspircd.org/inspircd.
+
+Bug reports and feature requests can be filed at https://github.com/inspircd/inspircd/issues.
diff --git a/make/template/inspircd.service b/make/template/inspircd.service
new file mode 100644
index 000000000..e29aa593f
--- /dev/null
+++ b/make/template/inspircd.service
@@ -0,0 +1,37 @@
+%platform linux
+#
+# InspIRCd -- Internet Relay Chat Daemon
+#
+# Copyright (C) 2014 Peter Powell <petpow@saberuk.com>
+#
+# This file is part of InspIRCd. InspIRCd is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+
+[Unit]
+After=network.target
+Description=InspIRCd - Internet Relay Chat Daemon
+Requires=network.target
+
+[Service]
+ExecReload=@SCRIPT_DIR@/inspircd rehash
+ExecStart=@SCRIPT_DIR@/inspircd start
+ExecStop=@SCRIPT_DIR@/inspircd stop
+PIDFile=@DATA_DIR@/inspircd.pid
+Restart=on-failure
+Type=forking
+User=@USER@
+Group=@GROUP@
+
+[Install]
+WantedBy=multi-user.target
diff --git a/make/template/main.mk b/make/template/main.mk
index 6979e1c74..15d2fa863 100644
--- a/make/template/main.mk
+++ b/make/template/main.mk
@@ -1,3 +1,4 @@
+%target GNUmakefile
#
# InspIRCd -- Internet Relay Chat Daemon
#
@@ -24,142 +25,133 @@
# make/template/main.mk. Any changes made to the generated
# files will go away whenever it is regenerated!
#
-# Please do not edit unless you know what you're doing. This
-# needs to work in both GNU and BSD make; it is mangled for
-# them by configure.
+# Please do not edit unless you know what you're doing.
#
-CC = @CC@
-SYSTEM = @SYSTEM@
-BUILDPATH = @BUILD_DIR@
+CXX = @CXX@
+COMPILER = @COMPILER_NAME@
+SYSTEM = @SYSTEM_NAME@
+BUILDPATH ?= $(PWD)/build
SOCKETENGINE = @SOCKETENGINE@
-CXXFLAGS = -pipe -fPIC -DPIC
-LDLIBS = -pthread -lstdc++
-LDFLAGS =
-CORELDFLAGS = -rdynamic -L. $(LDFLAGS)
-PICLDFLAGS = -fPIC -shared -rdynamic $(LDFLAGS)
+CORECXXFLAGS = -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -pipe -Iinclude -Wall -Wextra -Wfatal-errors -Wno-unused-parameter -Wshadow
+LDLIBS = -lstdc++
+CORELDFLAGS = -rdynamic -L.
+PICLDFLAGS = -fPIC -shared -rdynamic
BASE = "$(DESTDIR)@BASE_DIR@"
CONPATH = "$(DESTDIR)@CONFIG_DIR@"
+MANPATH = "$(DESTDIR)@MANUAL_DIR@"
MODPATH = "$(DESTDIR)@MODULE_DIR@"
LOGPATH = "$(DESTDIR)@LOG_DIR@"
DATPATH = "$(DESTDIR)@DATA_DIR@"
BINPATH = "$(DESTDIR)@BINARY_DIR@"
+SCRPATH = "$(DESTDIR)@SCRIPT_DIR@"
INSTALL = install
-INSTUID = @UID@
-INSTMODE_DIR = 0755
-INSTMODE_BIN = 0755
-INSTMODE_LIB = 0644
-
-@IFEQ $(CC) icpc
- CXXFLAGS += -Wshadow
-@ELSE
- CXXFLAGS += -pedantic -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute -Wall
-@ENDIF
-
-
-@IFEQ $(SYSTEM) linux
+INSTMODE_DIR = 0750
+INSTMODE_BIN = 0750
+INSTMODE_LIB = 0640
+
+ifneq ($(COMPILER), ICC)
+ CORECXXFLAGS += -Woverloaded-virtual -Wshadow
+ifneq ($(SYSTEM), openbsd)
+ CORECXXFLAGS += -pedantic -Wformat=2 -Wmissing-format-attribute -Wno-format-nonliteral
+endif
+endif
+
+ifneq ($(SYSTEM), darwin)
+ LDLIBS += -pthread
+endif
+
+ifeq ($(SYSTEM), linux)
LDLIBS += -ldl -lrt
-@ENDIF
-@IFEQ $(SYSTEM) gnukfreebsd
+endif
+ifeq ($(SYSTEM), gnukfreebsd)
LDLIBS += -ldl -lrt
-@ENDIF
-@IFEQ $(SYSTEM) gnu
+endif
+ifeq ($(SYSTEM), gnu)
LDLIBS += -ldl -lrt
-@ENDIF
-@IFEQ $(SYSTEM) solaris
+endif
+ifeq ($(SYSTEM), solaris)
LDLIBS += -lsocket -lnsl -lrt -lresolv
INSTALL = ginstall
-@ENDIF
-@IFEQ $(SYSTEM) sunos
- LDLIBS += -lsocket -lnsl -lrt -lresolv
- INSTALL = ginstall
-@ENDIF
-@IFEQ $(SYSTEM) darwin
- CXXFLAGS += -DDARWIN -frtti
+endif
+ifeq ($(SYSTEM), darwin)
LDLIBS += -ldl
- CORELDFLAGS = -dynamic -bind_at_load -L. $(LDFLAGS)
- PICLDFLAGS = -fPIC -shared -twolevel_namespace -undefined dynamic_lookup $(LDFLAGS)
-@ENDIF
-@IFEQ $(SYSTEM) interix
- CXXFLAGS += -D_ALL_SOURCE -I/usr/local/include
-@ENDIF
-
-@IFNDEF D
- D=0
-@ENDIF
-
-GCC6=@GCC6@
-@IFEQ $(GCC6) true
- CXXFLAGS += -fno-delete-null-pointer-checks
-@ENDIF
+ CORELDFLAGS = -dynamic -bind_at_load -L.
+ PICLDFLAGS = -fPIC -shared -twolevel_namespace -undefined dynamic_lookup
+endif
+ifeq ($(SYSTEM), haiku)
+ LDLIBS = -lnetwork -lstdc++
+ CORELDFLAGS = -L.
+ PICLDFLAGS = -fPIC -shared
+endif
+
+ifndef INSPIRCD_DEBUG
+ INSPIRCD_DEBUG=0
+endif
DBGOK=0
-@IFEQ $(D) 0
- CXXFLAGS += -O2
-@IFEQ $(CC) g++
- CXXFLAGS += -g1
-@ENDIF
+ifeq ($(INSPIRCD_DEBUG), 0)
+ CORECXXFLAGS += -fno-rtti -O2
+ifeq ($(COMPILER), GCC)
+ CORECXXFLAGS += -g1
+endif
HEADER = std-header
DBGOK=1
-@ENDIF
-@IFEQ $(D) 1
- CXXFLAGS += -O0 -g3 -Werror
+endif
+ifeq ($(INSPIRCD_DEBUG), 1)
+ CORECXXFLAGS += -O0 -g3 -Werror -DINSPIRCD_ENABLE_RTTI
HEADER = debug-header
DBGOK=1
-@ENDIF
-@IFEQ $(D) 2
- CXXFLAGS += -O2 -g3
+endif
+ifeq ($(INSPIRCD_DEBUG), 2)
+ CORECXXFLAGS += -fno-rtti -O2 -g3
HEADER = debug-header
DBGOK=1
-@ENDIF
+endif
+ifeq ($(INSPIRCD_DEBUG), 3)
+ CORECXXFLAGS += -fno-rtti -O0 -g0
+ HEADER = std-header
+ DBGOK=1
+endif
FOOTER = finishmessage
-CXXFLAGS += -Iinclude
-
-@GNU_ONLY MAKEFLAGS += --no-print-directory
+MAKEFLAGS += --no-print-directory
-@GNU_ONLY SOURCEPATH = $(shell /bin/pwd)
-@BSD_ONLY SOURCEPATH != /bin/pwd
+SOURCEPATH = $(shell pwd)
-@IFDEF V
- RUNCC = $(CC)
- RUNLD = $(CC)
- VERBOSE = -v
-@ELSE
- @GNU_ONLY MAKEFLAGS += --silent
- @BSD_ONLY MAKE += -s
- RUNCC = perl "$(SOURCEPATH)/make/run-cc.pl" $(CC)
- RUNLD = perl "$(SOURCEPATH)/make/run-cc.pl" $(CC)
- VERBOSE =
-@ENDIF
+ifndef INSPIRCD_VERBOSE
+ MAKEFLAGS += --silent
+endif
-@IFDEF PURE_STATIC
- CXXFLAGS += -DPURE_STATIC
-@ENDIF
+# Append any flags set in the environment after the base flags so
+# that they can be overridden if necessary.
+CORECXXFLAGS += $(CPPFLAGS) $(CXXFLAGS)
+CORELDFLAGS += $(LDFLAGS)
+PICLDFLAGS += $(LDFLAGS)
-@DO_EXPORT RUNCC RUNLD CXXFLAGS LDLIBS PICLDFLAGS VERBOSE SOCKETENGINE CORELDFLAGS
-@DO_EXPORT SOURCEPATH BUILDPATH PURE_STATIC SPLIT_CC
+export BUILDPATH
+export CORECXXFLAGS
+export CORELDFLAGS
+export CXX
+export INSPIRCD_VERBOSE
+export LDLIBS
+export PICLDFLAGS
+export SOCKETENGINE
+export SOURCEPATH
# Default target
TARGET = all
-@IFDEF M
+ifdef INSPIRCD_TARGET
HEADER = mod-header
FOOTER = mod-footer
- @BSD_ONLY TARGET = modules/${M:S/.so$//}.so
- @GNU_ONLY TARGET = modules/$(M:.so=).so
-@ENDIF
+ TARGET = $(INSPIRCD_TARGET)
+endif
-@IFDEF T
- HEADER =
- FOOTER = target
- TARGET = $(T)
-@ENDIF
-
-@IFEQ $(DBGOK) 0
+ifeq ($(DBGOK), 0)
HEADER = unknown-debug-level
-@ENDIF
+endif
all: $(FOOTER)
@@ -168,7 +160,7 @@ target: $(HEADER)
cd "$(BUILDPATH)"; $(MAKEENV) $(MAKE) -f real.mk $(TARGET)
debug:
- @${MAKE} D=1 all
+ @${MAKE} INSPIRCD_DEBUG=1 all
debug-header:
@echo "*************************************"
@@ -185,11 +177,7 @@ debug-header:
@echo "*************************************"
mod-header:
-@IFDEF PURE_STATIC
- @echo 'Cannot build single modules in pure-static build'
- @exit 1
-@ENDIF
- @echo 'Building single module:'
+ @echo 'Building specific targets:'
mod-footer: target
@echo 'To install, copy $(BUILDPATH)/$(TARGET) to $(MODPATH)'
@@ -201,8 +189,8 @@ std-header:
@echo "* *"
@echo "* This will take a *long* time. *"
@echo "* Why not read our docs at *"
- @echo "* http://docs.inspircd.org *"
- @echo "* while you wait for make to run? *"
+ @echo "* https://docs.inspircd.org *"
+ @echo "* while you wait for Make to run? *"
@echo "*************************************"
finishmessage: target
@@ -211,36 +199,36 @@ finishmessage: target
@echo "* BUILD COMPLETE! *"
@echo "* *"
@echo "* To install InspIRCd, type: *"
- @echo "* make install *"
+ @echo "* 'make install' *"
@echo "*************************************"
install: target
- @if [ "$(INSTUID)" = 0 -o "$(INSTUID)" = root ]; then \
- echo ""; \
- echo "Error: You must specify a non-root UID for the server"; \
- echo ""; \
- echo "If you are making a package, please specify using ./configure --uid"; \
- echo "Otherwise, rerun using 'make INSTUID=irc install', where 'irc' is the user"; \
- echo "who will be running the ircd. You will also need to modify the start script."; \
- echo ""; \
- exit 1; \
- fi
- @-$(INSTALL) -d -o $(INSTUID) -m $(INSTMODE_DIR) $(BASE)
- @-$(INSTALL) -d -o $(INSTUID) -m $(INSTMODE_DIR) $(DATPATH)
- @-$(INSTALL) -d -o $(INSTUID) -m $(INSTMODE_DIR) $(LOGPATH)
- @-$(INSTALL) -d -m $(INSTMODE_DIR) $(BINPATH)
- @-$(INSTALL) -d -m $(INSTMODE_DIR) $(CONPATH)/examples/aliases
- @-$(INSTALL) -d -m $(INSTMODE_DIR) $(CONPATH)/examples/modules
- @-$(INSTALL) -d -m $(INSTMODE_DIR) $(MODPATH)
- [ "$(BUILDPATH)/bin/" -ef $(BINPATH) ] || $(INSTALL) -m $(INSTMODE_BIN) "$(BUILDPATH)/bin/inspircd" $(BINPATH)
-@IFNDEF PURE_STATIC
- [ "$(BUILDPATH)/modules/" -ef $(MODPATH) ] || $(INSTALL) -m $(INSTMODE_LIB) "$(BUILDPATH)/modules/"*.so $(MODPATH)
-@ENDIF
- -$(INSTALL) -m $(INSTMODE_BIN) @STARTSCRIPT@ $(BASE) 2>/dev/null
- -$(INSTALL) -m $(INSTMODE_LIB) tools/gdbargs $(BASE)/.gdbargs 2>/dev/null
- -$(INSTALL) -m $(INSTMODE_LIB) docs/conf/*.example $(CONPATH)/examples
- -$(INSTALL) -m $(INSTMODE_LIB) docs/conf/aliases/*.example $(CONPATH)/examples/aliases
- -$(INSTALL) -m $(INSTMODE_LIB) docs/conf/modules/*.example $(CONPATH)/examples/modules
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(BASE)
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(DATPATH)
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(LOGPATH)
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(BINPATH)
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(CONPATH)/examples/services
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(CONPATH)/examples/sql
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(MANPATH)
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(MODPATH)
+ @-$(INSTALL) -d -g @GID@ -o @UID@ -m $(INSTMODE_DIR) $(SCRPATH)
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_BIN) "$(BUILDPATH)/bin/inspircd" $(BINPATH)
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) "$(BUILDPATH)/modules/"*.so $(MODPATH)
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_BIN) @CONFIGURE_DIRECTORY@/inspircd $(SCRPATH) 2>/dev/null
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) .gdbargs $(SCRPATH)/.gdbargs 2>/dev/null
+ifeq ($(SYSTEM), darwin)
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_BIN) @CONFIGURE_DIRECTORY@/org.inspircd.plist $(SCRPATH) 2>/dev/null
+endif
+ifeq ($(SYSTEM), linux)
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) @CONFIGURE_DIRECTORY@/inspircd.service $(SCRPATH) 2>/dev/null
+endif
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) @CONFIGURE_DIRECTORY@/inspircd.1 $(MANPATH) 2>/dev/null
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) @CONFIGURE_DIRECTORY@/inspircd-genssl.1 $(MANPATH) 2>/dev/null
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_BIN) tools/genssl $(BINPATH)/inspircd-genssl 2>/dev/null
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) docs/conf/*.example $(CONPATH)/examples
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) docs/conf/services/*.example $(CONPATH)/examples/services
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) docs/sql/*.sql $(CONPATH)/examples/sql
+ -$(INSTALL) -g @GID@ -o @UID@ -m $(INSTMODE_LIB) *.pem $(CONPATH) 2>/dev/null
@echo ""
@echo "*************************************"
@echo "* INSTALL COMPLETE! *"
@@ -251,15 +239,12 @@ install: target
@echo ' Binaries:' $(BINPATH)
@echo ' Modules:' $(MODPATH)
@echo ' Data:' $(DATPATH)
- @echo 'To start the ircd, run:' $(BASE)/inspircd start
+ @echo 'To start the ircd, run:' $(SCRPATH)/inspircd start
@echo 'Remember to create your config file:' $(CONPATH)/inspircd.conf
@echo 'Examples are available at:' $(CONPATH)/examples/
-@GNU_ONLY RCS_FILES = $(wildcard .git/index src/version.sh)
-@BSD_ONLY RCS_FILES = src/version.sh
-GNUmakefile BSDmakefile: make/template/main.mk configure $(RCS_FILES)
- ./configure -update
-@BSD_ONLY .MAKEFILEDEPS: BSDmakefile
+GNUmakefile: make/template/main.mk src/version.sh configure @CONFIGURE_CACHE_FILE@
+ ./configure --update
clean:
@echo Cleaning...
@@ -272,21 +257,20 @@ clean:
deinstall:
-rm -f $(BINPATH)/inspircd
-rm -rf $(CONPATH)/examples
- -rm -f $(MODPATH)/cmd_*.so
+ -rm -f $(MANPATH)/inspircd.1
+ -rm -f $(MANPATH)/inspircd-genssl.1
-rm -f $(MODPATH)/m_*.so
- -rm -f $(BASE)/.gdbargs
- -rm -f $(BASE)/org.inspircd.plist
-
-squeakyclean: distclean
+ -rm -f $(MODPATH)/core_*.so
+ -rm -f $(SCRPATH)/.gdbargs
+ -rm -f $(SCRPATH)/inspircd.service
+ -rm -f $(SCRPATH)/org.inspircd.plist
configureclean:
- rm -f .config.cache
- rm -f BSDmakefile
+ rm -f .gdbargs
+ -rm -f Makefile
rm -f GNUmakefile
- rm -f include/inspircd_config.h
- rm -f include/inspircd_version.h
- rm -f inspircd
- -rm -f org.inspircd.plist
+ rm -f include/config.h
+ rm -rf @CONFIGURE_DIRECTORY@
distclean: clean configureclean
-rm -rf "$(SOURCEPATH)/run"
@@ -298,11 +282,12 @@ help:
@echo 'Use: ${MAKE} [flags] [targets]'
@echo ''
@echo 'Flags:'
- @echo ' V=1 Show the full command being executed instead of "BUILD: dns.cpp"'
- @echo ' D=1 Enable debug build, for module development or crash tracing'
- @echo ' D=2 Enable debug build with optimizations, for detailed backtraces'
- @echo ' DESTDIR= Specify a destination root directory (for tarball creation)'
- @echo ' -j <N> Run a parallel build using N jobs'
+ @echo ' INSPIRCD_VERBOSE=1 Show the full command being executed instead of "BUILD: dns.cpp"'
+ @echo ' INSPIRCD_DEBUG=1 Enable debug build, for module development or crash tracing'
+ @echo ' INSPIRCD_DEBUG=2 Enable debug build with optimizations, for detailed backtraces'
+ @echo ' INSPIRCD_DEBUG=3 Enable fast build with no optimisations or symbols, for Travis CI'
+ @echo ' DESTDIR= Specify a destination root directory (for tarball creation)'
+ @echo ' -j <N> Run a parallel build using N jobs'
@echo ''
@echo 'Targets:'
@echo ' all Complete build of InspIRCd, without installing (default)'
@@ -310,10 +295,8 @@ help:
@echo ' Currently installs to ${BASE}'
@echo ' debug Compile a debug build. Equivalent to "make D=1 all"'
@echo ''
- @echo ' M=m_foo Builds a single module (cmd_foo also works here)'
- @echo ' T=target Builds a user-specified target, such as "inspircd" or "modules"'
- @echo ' Other targets are specified by their path in the build directory'
- @echo ' Multiple targets may be separated by a space'
+ @echo ' INSPIRCD_TARGET=target Builds a user-specified target, such as "inspircd" or "core_dns"'
+ @echo ' Multiple targets may be separated by a space'
@echo ''
@echo ' clean Cleans object files produced by the compile'
@echo ' distclean Cleans all generated files (build, configure, run, etc)'
@@ -322,4 +305,4 @@ help:
.NOTPARALLEL:
-.PHONY: all target debug debug-header mod-header mod-footer std-header finishmessage install clean deinstall squeakyclean configureclean help
+.PHONY: all target debug debug-header mod-header mod-footer std-header finishmessage install clean deinstall configureclean help
diff --git a/make/template/org.inspircd.plist b/make/template/org.inspircd.plist
index 4dac209f6..ae4e90916 100644
--- a/make/template/org.inspircd.plist
+++ b/make/template/org.inspircd.plist
@@ -1,3 +1,4 @@
+%platform darwin
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
@@ -26,6 +27,8 @@
<key>StandardErrorPath</key>
<string>@LOG_DIR@/launchd-stderr.log</string>
<key>UserName</key>
- <string>ircdaemon</string>
+ <string>@USER@</string>
+ <key>GroupName</key>
+ <string>@GROUP@</string>
</dict>
</plist>
diff --git a/make/check_epoll.cpp b/make/test/arc4random_buf.cpp
index a5ed1c10b..86f74f624 100644
--- a/make/check_epoll.cpp
+++ b/make/test/arc4random_buf.cpp
@@ -1,7 +1,7 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
- * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2018 Peter Powell <petpow@saberuk.com>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
@@ -17,9 +17,10 @@
*/
-#include <sys/epoll.h>
+#include <stdlib.h>
int main() {
- int fd = epoll_create(1);
- return (fd < 0);
+ char buffer[100];
+ arc4random_buf(buffer, sizeof(buffer));
+ return 0;
}
diff --git a/make/check_stdint.cpp b/make/test/clock_gettime.cpp
index fbd01b80d..d111d591f 100644
--- a/make/check_stdint.cpp
+++ b/make/test/clock_gettime.cpp
@@ -1,7 +1,7 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
- * Copyright (C) 2015 Peter Powell <petpow@saberuk.com>
+ * Copyright (C) 2013 Peter Powell <petpow@saberuk.com>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
@@ -17,9 +17,10 @@
*/
-#include <stdint.h>
+#include <time.h>
int main() {
- uint32_t ret = 0;
- return ret;
+ timespec time_spec;
+ clock_gettime(CLOCK_REALTIME, &time_spec);
+ return 0;
}
diff --git a/make/test/compiler.cpp b/make/test/compiler.cpp
new file mode 100644
index 000000000..f01423325
--- /dev/null
+++ b/make/test/compiler.cpp
@@ -0,0 +1,39 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2016 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2014-2015 Peter Powell <petpow@saberuk.com>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <iostream>
+#if defined _LIBCPP_VERSION
+# include <array>
+# include <type_traits>
+# include <unordered_map>
+#else
+# include <tr1/array>
+# include <tr1/type_traits>
+# include <tr1/unordered_map>
+#endif
+
+#if defined __llvm__ && !defined __clang__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1
+# error "LLVM-GCC 4.2.1 has broken visibility support."
+#endif
+
+int main() {
+ std::cout << "Hello, World!" << std::endl;
+ return 0;
+}
diff --git a/make/test/compiler_info.cpp b/make/test/compiler_info.cpp
new file mode 100644
index 000000000..10b156fc8
--- /dev/null
+++ b/make/test/compiler_info.cpp
@@ -0,0 +1,41 @@
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2017 Peter Powell <petpow@saberuk.com>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <iostream>
+
+#if defined __INTEL_COMPILER // Also defines __clang__ and __GNUC__
+# define INSPIRCD_COMPILER_NAME "Intel"
+# define INSPIRCD_COMPILER_VERSION (__INTEL_COMPILER / 100) << '.' << (__INTEL_COMPILER % 100)
+#elif defined __clang__ // Also defines __GNUC__
+# if defined __apple_build_version__
+# define INSPIRCD_COMPILER_NAME "AppleClang"
+# else
+# define INSPIRCD_COMPILER_NAME "Clang"
+# endif
+# define INSPIRCD_COMPILER_VERSION __clang_major__ << '.' << __clang_minor__
+#elif defined __GNUC__
+# define INSPIRCD_COMPILER_NAME "GCC"
+# define INSPIRCD_COMPILER_VERSION __GNUC__ << '.' << __GNUC_MINOR__
+#endif
+
+int main() {
+ std::cout << "NAME " << INSPIRCD_COMPILER_NAME << std::endl
+ << "VERSION " << INSPIRCD_COMPILER_VERSION << std::endl;
+ return 0;
+}
diff --git a/make/check_eventfd.cpp b/make/test/eventfd.cpp
index 9b38b793b..9b38b793b 100644
--- a/make/check_eventfd.cpp
+++ b/make/test/eventfd.cpp
diff --git a/make/check_kqueue.cpp b/make/test/kqueue.cpp
index 6034253df..708677adf 100644
--- a/make/check_kqueue.cpp
+++ b/make/test/kqueue.cpp
@@ -1,7 +1,7 @@
/*
* InspIRCd -- Internet Relay Chat Daemon
*
- * Copyright (C) 2015 Peter Powell <petpow@saberuk.com>
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
*
* This file is part of InspIRCd. InspIRCd is free software: you can
* redistribute it and/or modify it under the terms of the GNU General Public
diff --git a/make/unit-cc.pl b/make/unit-cc.pl
index a494fb74b..18e60d759 100755
--- a/make/unit-cc.pl
+++ b/make/unit-cc.pl
@@ -19,38 +19,25 @@
#
+BEGIN {
+ push @INC, $ENV{SOURCEPATH};
+ require 5.10.0;
+}
+
use strict;
-use warnings;
-BEGIN { push @INC, $ENV{SOURCEPATH}; }
-use make::configure;
+use warnings FATAL => qw(all);
+
+use File::Spec::Functions qw(abs2rel);
+
+use make::console;
+use make::directive;
chdir $ENV{BUILDPATH};
my $type = shift;
my $out = shift;
-my $verbose = ($type =~ s/-v$//);
-
-## BEGIN HACK: REMOVE IN 2.2!
-sub read_config_cache {
- my %cfg = ();
- open(CACHE, '../.config.cache') or return %cfg;
- while (my $line = <CACHE>) {
- next if $line =~ /^\s*($|\#)/;
- my ($key, $value) = ($line =~ /^(\S+)="(.*)"$/);
- $cfg{$key} = $value;
- }
- close(CACHE);
- return %cfg;
-}
-
-our %config = read_config_cache();
-## END HACK
-if ($type eq 'gen-ld') {
- do_static_find(@ARGV);
-} elsif ($type eq 'static-ld') {
- do_static_link(@ARGV);
-} elsif ($type eq 'core-ld') {
+if ($type eq 'core-ld') {
do_core_link(@ARGV);
} elsif ($type eq 'link-dir') {
do_link_dir(@ARGV);
@@ -65,44 +52,34 @@ if ($type eq 'gen-ld') {
}
exit 1;
-sub do_static_find {
- my @flags;
- for my $file (@ARGV) {
- push @flags, getlinkerflags($file);
+sub message($$$) {
+ my ($type, $file, $command) = @_;
+ if ($ENV{INSPIRCD_VERBOSE}) {
+ print "$command\n";
+ } else {
+ print_format "\t<|GREEN $type:|>\t\t$file\n";
}
- open F, '>', $out;
- print F join ' ', @flags;
- close F;
- exit 0;
}
-sub do_static_link {
- my $execstr = "$ENV{RUNLD} -o $out $ENV{CORELDFLAGS}";
- for (@ARGV) {
- if (/\.cmd$/) {
- open F, '<', $_;
- my $libs = <F>;
- chomp $libs;
- $execstr .= ' '.$libs;
- close F;
- } else {
- $execstr .= ' '.$_;
- }
- }
- $execstr .= ' '.$ENV{LDLIBS};
- print "$execstr\n" if $verbose;
- exec $execstr;
+sub rpath($) {
+ my $message = shift;
+ $message =~ s/-L(\S+)/-Wl,-rpath,$1 -L$1/g unless defined $ENV{INSPIRCD_DISABLE_RPATH};
+ return $message;
}
sub do_core_link {
- my $execstr = "$ENV{RUNLD} -o $out $ENV{CORELDFLAGS} @_ $ENV{LDLIBS}";
- print "$execstr\n" if $verbose;
+ my $execstr = "$ENV{CXX} -o $out $ENV{CORELDFLAGS} @_ $ENV{LDLIBS}";
+ message 'LINK', $out, $execstr;
exec $execstr;
}
sub do_link_dir {
- my $execstr = "$ENV{RUNLD} -o $out $ENV{PICLDFLAGS} @_";
- print "$execstr\n" if $verbose;
+ my ($dir, $link_flags) = (shift, '');
+ for my $file (<$dir/*.cpp>) {
+ $link_flags .= rpath(get_directive($file, 'LinkerFlags', '')) . ' ';
+ }
+ my $execstr = "$ENV{CXX} -o $out $ENV{PICLDFLAGS} @_ $link_flags";
+ message 'LINK', $out, $execstr;
exec $execstr;
}
@@ -111,27 +88,22 @@ sub do_compile {
my $flags = '';
my $libs = '';
- my $binary = $ENV{RUNCC};
if ($do_compile) {
- $flags = $ENV{CXXFLAGS};
- $flags =~ s/ -pedantic// if nopedantic($file);
- $flags .= ' ' . getcompilerflags($file);
+ $flags = $ENV{CORECXXFLAGS} . ' ' . get_directive($file, 'CompilerFlags', '');
- if ($file =~ m#(?:^|/)((?:m|cmd)_[^/. ]+)(?:\.cpp|/.*\.cpp)$#) {
- $flags .= ' -DMODNAME='.$1.'.so';
+ if ($file =~ m#(?:^|/)((?:m|core)_[^/. ]+)(?:\.cpp|/.*\.cpp)$#) {
+ $flags .= ' -DMODNAME=\\"'.$1.'\\"';
}
- } else {
- $binary = $ENV{RUNLD};
}
if ($do_link) {
$flags = join ' ', $flags, $ENV{PICLDFLAGS};
- $libs = join ' ', getlinkerflags($file);
+ $libs = rpath(get_directive($file, 'LinkerFlags', ''));
} else {
$flags .= ' -c';
}
- my $execstr = "$binary -o $out $flags $file $libs";
- print "$execstr\n" if $verbose;
+ my $execstr = "$ENV{CXX} -o $out $flags $file $libs";
+ message 'BUILD', abs2rel($file, "$ENV{SOURCEPATH}/src"), $execstr;
exec $execstr;
}
diff --git a/make/utilities.pm b/make/utilities.pm
deleted file mode 100644
index baba584ad..000000000
--- a/make/utilities.pm
+++ /dev/null
@@ -1,471 +0,0 @@
-#
-# InspIRCd -- Internet Relay Chat Daemon
-#
-# Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
-# Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc>
-# Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
-# Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
-#
-# This file is part of InspIRCd. InspIRCd is free software: you can
-# redistribute it and/or modify it under the terms of the GNU General Public
-# License as published by the Free Software Foundation, version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-
-
-package make::utilities;
-
-require 5.8.0;
-
-use strict;
-use warnings FATAL => qw(all);
-
-use Exporter 'import';
-use POSIX;
-use File::Temp;
-use Getopt::Long;
-use Fcntl;
-our @EXPORT = qw(make_rpath pkgconfig_get_include_dirs pkgconfig_get_lib_dirs pkgconfig_check_version translate_functions promptstring);
-
-# Parse the output of a *_config program,
-# such as pcre_config, take out the -L
-# directive and return an rpath for it.
-
-# \e[1;32msrc/Makefile\e[0m
-
-my %already_added = ();
-my $if_skip_lines = 0;
-
-sub promptstring($$$$$)
-{
- my ($prompt, $configitem, $default, $package, $commandlineswitch) = @_;
- my $var;
- if (!$main::interactive)
- {
- my $opt_commandlineswitch;
- GetOptions ("$commandlineswitch=s" => \$opt_commandlineswitch);
- if (defined $opt_commandlineswitch)
- {
- print "\e[1;32m$opt_commandlineswitch\e[0m\n";
- $var = $opt_commandlineswitch;
- }
- else
- {
- die "Could not detect $package! Please specify the $prompt via the command line option \e[1;32m--$commandlineswitch=\"/path/to/file\"\e[0m";
- }
- }
- else
- {
- print "\nPlease enter the $prompt?\n";
- print "[\e[1;32m$default\e[0m] -> ";
- chomp($var = <STDIN>);
- }
- if ($var eq "")
- {
- $var = $default;
- }
- $main::config{$configitem} = $var;
-}
-
-sub make_rpath($;$)
-{
- my ($executable, $module) = @_;
- return "" if defined $ENV{DISABLE_RPATH};
- chomp(my $data = `$executable`);
- my $output = "";
- while ($data =~ /-L(\S+)/)
- {
- my $libpath = $1;
- if (!exists $already_added{$libpath})
- {
- print "Adding runtime library path to \e[1;32m$module\e[0m ... \e[1;32m$libpath\e[0m\n";
- $already_added{$libpath} = 1;
- }
- $output .= "-Wl,-rpath -Wl,$libpath -L$libpath ";
- $data =~ s/-L(\S+)//;
- }
- return $output;
-}
-
-sub extend_pkg_path()
-{
- return if defined $ENV{DISABLE_EXTEND_PKG_PATH};
- if (!exists $ENV{PKG_CONFIG_PATH})
- {
- $ENV{PKG_CONFIG_PATH} = "/usr/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
- }
- else
- {
- $ENV{PKG_CONFIG_PATH} .= ":/usr/local/lib/pkgconfig:/usr/local/libdata/pkgconfig:/usr/X11R6/libdata/pkgconfig";
- }
-}
-
-sub pkgconfig_get_include_dirs($$$;$)
-{
- my ($packagename, $headername, $defaults, $module) = @_;
-
- my $key = "default_includedir_$packagename";
- if (exists $main::config{$key})
- {
- print "Locating include directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
- my $ret = $main::config{$key};
- print "\e[1;32m$ret\e[0m (cached)\n";
- return $ret;
- }
-
- extend_pkg_path();
-
- print "Locating include directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
-
- my $v = `pkg-config --modversion $packagename 2>/dev/null`;
- my $ret = `pkg-config --cflags $packagename 2>/dev/null`;
- my $foo = "";
- if ((!defined $v) || ($v eq ""))
- {
- print "\e[31mCould not find $packagename via pkg-config\e[m (\e[1;32mplease install pkg-config\e[m)\n";
- my $locbin = $^O eq 'solaris' ? 'slocate' : 'locate';
- $foo = `$locbin "$headername" 2>/dev/null | head -n 1`;
- my $find = $foo =~ /(.+)\Q$headername\E/ ? $1 : '';
- chomp($find);
- if ((defined $find) && ($find ne "") && ($find ne $packagename))
- {
- print "(\e[1;32mFound via search\e[0m) ";
- $foo = "-I$1";
- }
- else
- {
- $foo = " ";
- undef $v;
- }
- $ret = "$foo";
- }
- if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
- {
- $ret = "$foo " . $defaults;
- }
- chomp($ret);
- if ((($ret eq " ") || (!defined $ret)) && ((!defined $v) || ($v eq "")))
- {
- my $key = "default_includedir_$packagename";
- if (exists $main::config{$key})
- {
- $ret = $main::config{$key};
- }
- else
- {
- $headername =~ s/^\///;
- promptstring("path to the directory containing $headername", $key, "/usr/include",$packagename,"$packagename-includes");
- $packagename =~ tr/a-z/A-Z/;
- if (defined $v)
- {
- $main::config{$key} = "-I$main::config{$key}" . " $defaults -DVERSION_$packagename=\"$v\"";
- }
- else
- {
- $main::config{$key} = "-I$main::config{$key}" . " $defaults -DVERSION_$packagename=\"0.0\"";
- }
- $main::config{$key} =~ s/^\s+//g;
- $ret = $main::config{$key};
- return $ret;
- }
- }
- else
- {
- chomp($v);
- my $key = "default_includedir_$packagename";
- $packagename =~ tr/a-z/A-Z/;
- $main::config{$key} = "$ret -DVERSION_$packagename=\"$v\"";
- $main::config{$key} =~ s/^\s+//g;
- $ret = $main::config{$key};
- print "\e[1;32m$ret\e[0m (version $v)\n";
- }
- $ret =~ s/^\s+//g;
- return $ret;
-}
-
-sub pkgconfig_check_version($$;$)
-{
- my ($packagename, $version, $module) = @_;
-
- extend_pkg_path();
-
- print "Checking version of package \e[1;32m$packagename\e[0m is >= \e[1;32m$version\e[0m... ";
-
- my $v = `pkg-config --modversion $packagename 2>/dev/null`;
- if (defined $v)
- {
- chomp($v);
- }
- if ((defined $v) && ($v ne ""))
- {
- if (!system "pkg-config --atleast-version $version $packagename")
- {
- print "\e[1;32mYes (version $v)\e[0m\n";
- return 1;
- }
- else
- {
- print "\e[1;32mNo (version $v)\e[0m\n";
- return 0;
- }
- }
- # If we didnt find it, we cant definitively say its too old.
- # Return ok, and let pkgconflibs() or pkgconfincludes() pick up
- # the missing library later on.
- print "\e[1;32mNo (not found)\e[0m\n";
- return 1;
-}
-
-sub pkgconfig_get_lib_dirs($$$;$)
-{
- my ($packagename, $libname, $defaults, $module) = @_;
-
- my $key = "default_libdir_$packagename";
- if (exists $main::config{$key})
- {
- print "Locating library directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
- my $ret = $main::config{$key};
- print "\e[1;32m$ret\e[0m (cached)\n";
- return $ret;
- }
-
- extend_pkg_path();
-
- print "Locating library directory for package \e[1;32m$packagename\e[0m for module \e[1;32m$module\e[0m... ";
-
- my $v = `pkg-config --modversion $packagename 2>/dev/null`;
- my $ret = `pkg-config --libs $packagename 2>/dev/null`;
-
- my $foo = "";
- if ((!defined $v) || ($v eq ""))
- {
- my $locbin = $^O eq 'solaris' ? 'slocate' : 'locate';
- $foo = `$locbin "$libname" | head -n 1`;
- $foo =~ /(.+)\Q$libname\E/;
- my $find = $1;
- chomp($find);
- if ((defined $find) && ($find ne "") && ($find ne $packagename))
- {
- print "(\e[1;32mFound via search\e[0m) ";
- $foo = "-L$1";
- }
- else
- {
- $foo = " ";
- undef $v;
- }
- $ret = "$foo";
- }
-
- if (($defaults ne "") && (($ret eq "") || (!defined $ret)))
- {
- $ret = "$foo " . $defaults;
- }
- chomp($ret);
- if ((($ret eq " ") || (!defined $ret)) && ((!defined $v) || ($v eq "")))
- {
- my $key = "default_libdir_$packagename";
- if (exists $main::config{$key})
- {
- $ret = $main::config{$key};
- }
- else
- {
- $libname =~ s/^\///;
- promptstring("path to the directory containing $libname", $key, "/usr/lib",$packagename,"$packagename-libs");
- $main::config{$key} = "-L$main::config{$key}" . " $defaults";
- $main::config{$key} =~ s/^\s+//g;
- $ret = $main::config{$key};
- return $ret;
- }
- }
- else
- {
- chomp($v);
- print "\e[1;32m$ret\e[0m (version $v)\n";
- my $key = "default_libdir_$packagename";
- $main::config{$key} = $ret;
- $main::config{$key} =~ s/^\s+//g;
- $ret =~ s/^\s+//g;
- }
- $ret =~ s/^\s+//g;
- return $ret;
-}
-
-# Translate a $CompileFlags etc line and parse out function calls
-# to functions within these modules at configure time.
-sub translate_functions($$)
-{
- my ($line,$module) = @_;
-
- eval
- {
- $module =~ /modules*\/(.+?)$/;
- $module = $1;
-
- # This is only a cursory check, just designed to catch casual accidental use of backticks.
- # There are pleanty of ways around it, but its not supposed to be for security, just checking
- # that people are using the new configuration api as theyre supposed to and not just using
- # backticks instead of eval(), being as eval has accountability. People wanting to get around
- # the accountability will do so anyway.
- if (($line =~ /`/) && ($line !~ /eval\(.+?`.+?\)/))
- {
- die "Developers should no longer use backticks in configuration macros. Please use exec() and eval() macros instead. Offending line: $line (In module: $module)";
- }
-
- if ($line =~ /if(gt|lt)\("(.+?)","(.+?)"\)/) {
- chomp(my $result = `$2 2>/dev/null`);
- if (($1 eq 'gt' && $result le $3) || ($1 eq 'lt' && $result ge $3)) {
- $line = substr $line, 0, $-[0];
- } else {
- $line =~ s/if$1\("$2","$3"\)//;
- }
- }
-
- if ($line =~ /ifuname\(\!"(\w+)"\)/)
- {
- my $uname = $1;
- if ($uname eq $^O)
- {
- $line = "";
- return "";
- }
-
- $line =~ s/ifuname\(\!"(.+?)"\)//;
- }
-
- if ($line =~ /ifuname\("(\w+)"\)/)
- {
- my $uname = $1;
- if ($uname ne $^O)
- {
- $line = "";
- return "";
- }
-
- $line =~ s/ifuname\("(.+?)"\)//;
- }
-
- if ($line =~ /if\("(\w+)"\)/)
- {
- if (defined $main::config{$1})
- {
- if (($main::config{$1} !~ /y/i) and ($main::config{$1} ne "1"))
- {
- $line = "";
- return "";
- }
- }
-
- $line =~ s/if\("(.+?)"\)//;
- }
- if ($line =~ /if\(\!"(\w+)"\)/)
- {
- if (!exists $main::config{$1})
- {
- $line = "";
- return "";
- }
- else
- {
- if (defined $1)
- {
- if (exists ($main::config{$1}) and (($main::config{$1} =~ /y/i) or ($main::config{$1} eq "1")))
- {
- $line = "";
- return "";
- }
- }
- }
-
- $line =~ s/if\(\!"(.+?)"\)//;
- }
- while ($line =~ /exec\("(.+?)"\)/)
- {
- print "Executing program for module \e[1;32m$module\e[0m ... \e[1;32m$1\e[0m\n";
- my $replace = `$1`;
- die $replace if ($replace =~ /Configuration failed/);
- chomp($replace);
- $line =~ s/exec\("(.+?)"\)/$replace/;
- }
- while ($line =~ /execruntime\("(.+?)"\)/)
- {
- $line =~ s/execruntime\("(.+?)"\)/`$1`/;
- }
- while ($line =~ /eval\("(.+?)"\)/)
- {
- print "Evaluating perl code for module \e[1;32m$module\e[0m ... ";
- my $tmpfile;
- do
- {
- $tmpfile = File::Temp::tmpnam();
- } until sysopen(TF, $tmpfile, O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0700);
- print "(Created and executed \e[1;32m$tmpfile\e[0m)\n";
- print TF $1;
- close TF;
- my $replace = `perl $tmpfile`;
- chomp($replace);
- unlink($tmpfile);
- $line =~ s/eval\("(.+?)"\)/$replace/;
- }
- while ($line =~ /pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/)
- {
- my $replace = pkgconfig_get_lib_dirs($1, $2, $3, $module);
- $line =~ s/pkgconflibs\("(.+?)","(.+?)","(.+?)"\)/$replace/;
- }
- while ($line =~ /pkgconfversion\("(.+?)","(.+?)"\)/)
- {
- if (pkgconfig_check_version($1, $2, $module) != 1)
- {
- die "Version of package $1 is too old. Please upgrade it to version \e[1;32m$2\e[0m or greater and try again.";
- }
- # This doesnt actually get replaced with anything
- $line =~ s/pkgconfversion\("(.+?)","(.+?)"\)//;
- }
- while ($line =~ /pkgconflibs\("(.+?)","(.+?)",""\)/)
- {
- my $replace = pkgconfig_get_lib_dirs($1, $2, "", $module);
- $line =~ s/pkgconflibs\("(.+?)","(.+?)",""\)/$replace/;
- }
- while ($line =~ /pkgconfincludes\("(.+?)","(.+?)",""\)/)
- {
- my $replace = pkgconfig_get_include_dirs($1, $2, "", $module);
- $line =~ s/pkgconfincludes\("(.+?)","(.+?)",""\)/$replace/;
- }
- while ($line =~ /pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/)
- {
- my $replace = pkgconfig_get_include_dirs($1, $2, $3, $module);
- $line =~ s/pkgconfincludes\("(.+?)","(.+?)","(.+?)"\)/$replace/;
- }
- while ($line =~ /rpath\("(.+?)"\)/)
- {
- my $replace = make_rpath($1,$module);
- $line =~ s/rpath\("(.+?)"\)/$replace/;
- }
- };
- if ($@)
- {
- my $err = $@;
- #$err =~ s/at .+? line \d+.*//g;
- print "\n\nConfiguration failed. The following error occured:\n\n$err\n";
- print "\nMake sure you have pkg-config installed\n";
- print "\nIn the case of gnutls configuration errors on debian,\n";
- print "Ubuntu, etc, you should ensure that you have installed\n";
- print "gnutls-bin as well as libgnutls-dev and libgnutls.\n";
- exit;
- }
- else
- {
- return $line;
- }
-}
-
-1;
-