summaryrefslogtreecommitdiff
path: root/make
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2014-04-14 12:42:22 +0100
committerAttila Molnar <attilamolnar@hush.com>2014-05-23 14:13:51 +0200
commite6d245a3e80c0e0c05476e5bd9c45a77e16fecec (patch)
tree490b8e34f3bd0f9b85959782a1760e2c7e55fcea /make
parentb512f1b9667ca0479d42e771082f3bc8d92c63a2 (diff)
Replace the configure templating system with something better.
A large amount of this code can be removed when buildtool is done as we will not need to worry about the differences between BSD and GNU Make.
Diffstat (limited to 'make')
-rw-r--r--make/configure.pm213
-rw-r--r--make/template/config.h38
-rw-r--r--make/template/gdbargs4
-rw-r--r--make/template/inspircd3
-rw-r--r--make/template/main.mk30
-rw-r--r--make/template/org.inspircd.plist1
-rw-r--r--make/utilities.pm43
7 files changed, 290 insertions, 42 deletions
diff --git a/make/configure.pm b/make/configure.pm
index de95e9161..905233835 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-2014 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>
@@ -30,8 +30,9 @@ package make::configure;
use strict;
use warnings FATAL => qw(all);
-use Cwd;
+use Cwd 'getcwd';
use Exporter 'import';
+use File::Basename 'basename';
use make::utilities;
@@ -39,10 +40,7 @@ our @EXPORT = qw(cmd_clean cmd_help cmd_update
read_configure_cache write_configure_cache
get_compiler_info find_compiler
run_test test_file test_header
- get_property get_revision
- dump_hash);
-
-my $revision;
+ dump_hash get_property parse_templates);
sub __get_socketengines() {
my @socketengines;
@@ -53,6 +51,34 @@ sub __get_socketengines() {
return @socketengines;
}
+# 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) = @_;
+
+ # Start off by populating with the config
+ my %settings = %$config;
+
+ # Compiler information
+ while (my ($key, $value) = each %{$compiler}) {
+ $settings{'COMPILER_' . $key} = $value;
+ }
+
+ # Version information
+ my %version = get_version();
+ while (my ($key, $value) = each %version) {
+ $settings{'VERSION_' . $key} = $value;
+ }
+
+ # Miscellaneous information
+ $settings{SYSTEM_NAME} = lc $^O;
+ chomp($settings{SYSTEM_NAME_VERSION} = `uname -sr 2>/dev/null`);
+
+ return %settings;
+}
+
sub cmd_clean {
unlink '.config.cache';
}
@@ -129,9 +155,9 @@ sub cmd_update {
exit 1;
}
print "Updating...\n";
- %main::config = read_configure_cache();
- %main::cxx = get_compiler_info($main::config{CXX});
- main::writefiles();
+ my %config = read_configure_cache();
+ my %compiler = get_compiler_info($config{CXX});
+ parse_templates(\%config, \%compiler);
print "Update complete!\n";
exit 0;
}
@@ -241,15 +267,7 @@ sub get_property($$;$)
return defined $default ? $default : '';
}
-sub get_revision {
- return $revision if defined $revision;
- chomp(my $tags = `git describe --tags 2>/dev/null`);
- $revision = $tags || 'release';
- return $revision;
-}
-
-sub dump_hash()
-{
+sub dump_hash() {
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";
@@ -262,4 +280,163 @@ sub dump_hash()
print "\e[0mOpenSSL support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n";
}
+sub parse_templates($$) {
+
+ # These are actually hash references
+ my ($config, $compiler) = @_;
+
+ # Collect settings to be used when generating files
+ my %settings = __get_template_settings($config, $compiler);
+
+ # Iterate through files in make/template.
+ foreach (<make/template/*>) {
+ print "Parsing $_...\n";
+ open(TEMPLATE, $_);
+ my (@lines, $mode, @platforms, %targets);
+
+ # First pass: parse template variables and directives.
+ while (my $line = <TEMPLATE>) {
+ chomp $line;
+
+ # Does this line match a variable?
+ while ($line =~ /(@(\w+?)@)/) {
+ my ($variable, $name) = ($1, $2);
+ if (defined $settings{$name}) {
+ $line =~ s/$variable/$settings{$name}/;
+ } else {
+ print STDERR "Warning: unknown template variable '$name' in $_!\n";
+ last;
+ }
+ }
+
+ # 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') {
+ if ($2 =~ /(\w+)\s(.+)/) {
+ $targets{$1} = $2;
+ } else {
+ $targets{DEFAULT} = $2;
+ }
+ } else {
+ print STDERR "Warning: unknown template command '$1' in $_!\n";
+ push @lines, $line;
+ }
+ next;
+ }
+ push @lines, $line;
+ }
+ close(TEMPLATE);
+
+ # Only proceed if this file should be templated on this platform.
+ if ($#platforms < 0 || grep { $_ eq $^O } @platforms) {
+
+ # Add a default target if the template has not defined one.
+ unless (scalar keys %targets) {
+ $targets{DEFAULT} = basename $_;
+ }
+
+ # Second pass: parse makefile junk and write files.
+ while (my ($name, $target) = each %targets) {
+
+ # TODO: when buildtool is done this mess can be removed completely.
+ my @final_lines;
+ foreach my $line (@lines) {
+
+ # Are we parsing a makefile and does this line match a statement?
+ if ($name =~ /(?:BSD|GNU)_MAKE/ && $line =~ /^\s*\@(\w+)(?:\s+(.+))?$/) {
+ my @tokens = split /\s/, $2 if defined $2;
+ if ($1 eq 'DO_EXPORT' && defined $2) {
+ if ($name eq 'BSD_MAKE') {
+ foreach my $variable (@tokens) {
+ push @final_lines, "MAKEENV += $variable='\${$variable}'";
+ }
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "export $2";
+ }
+ } elsif ($1 eq 'ELSE') {
+ if ($name eq 'BSD_MAKE') {
+ push @final_lines, ".else";
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "else";
+ }
+ } elsif ($1 eq 'ENDIF') {
+ if ($name eq 'BSD_MAKE') {
+ push @final_lines, ".endif";
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "endif";
+ }
+ } elsif ($1 eq 'ELSIFEQ' && defined $2) {
+ if ($name eq 'BSD_MAKE') {
+ push @final_lines, ".elif $tokens[0] == $tokens[1]";
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "else ifeq ($tokens[0], $tokens[1])";
+ }
+ } elsif ($1 eq 'IFDEF' && defined $2) {
+ if ($name eq 'BSD_MAKE') {
+ push @final_lines, ".if defined($2)";
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "ifdef $2";
+ }
+ } elsif ($1 eq 'IFEQ' && defined $2) {
+ if ($name eq 'BSD_MAKE') {
+ push @final_lines, ".if $tokens[0] == $tokens[1]";
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "ifeq ($tokens[0],$tokens[1])";
+ }
+ } elsif ($1 eq 'IFNEQ' && defined $2) {
+ if ($name eq 'BSD_MAKE') {
+ push @final_lines, ".if $tokens[0] != $tokens[1]";
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "ifneq ($tokens[0],$tokens[1])";
+ }
+ } elsif ($1 eq 'IFNDEF' && defined $2) {
+ if ($name eq 'BSD_MAKE') {
+ push @final_lines, ".if !defined($2)";
+ } elsif ($name eq 'GNU_MAKE') {
+ push @final_lines, "ifndef $2";
+ }
+ } elsif ($1 eq 'TARGET' && defined $2) {
+ if ($tokens[0] eq $name) {
+ push @final_lines, substr($2, length($tokens[0]) + 1);
+ }
+ } elsif ($1 !~ /[A-Z]/) {
+ # HACK: silently ignore if lower case as these are probably make commands.
+ push @final_lines, $line;
+ } else {
+ print STDERR "Warning: unknown template command '$1' in $_!\n";
+ push @final_lines, $line;
+ }
+ next;
+ }
+
+ push @final_lines, $line;
+ }
+
+ # Write the template file.
+ print "Writing $target...\n";
+ open(TARGET, ">$target");
+ foreach (@final_lines) {
+ print TARGET $_, "\n";
+ }
+ close(TARGET);
+
+ # Set file permissions.
+ if (defined $mode) {
+ chmod $mode, $target;
+ }
+ }
+ }
+ }
+}
+
1;
diff --git a/make/template/config.h b/make/template/config.h
new file mode 100644
index 000000000..6aa593975
--- /dev/null
+++ b/make/template/config.h
@@ -0,0 +1,38 @@
+/*
+ * 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/>.
+ */
+
+
+#pragma once
+
+#define BRANCH "InspIRCd-@VERSION_MAJOR@.@VERSION_MINOR@"
+#define VERSION "InspIRCd-@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@"
+#define REVISION "@VERSION_LABEL@"
+#define SYSTEM "@SYSTEM_NAME_VERSION@"
+
+#define CONFIG_PATH "@CONFIG_DIR@"
+#define DATA_PATH "@DATA_DIR@"
+#define LOG_PATH "@LOG_DIR@"
+#define MOD_PATH "@MODULE_DIR@"
+
+#define INSPIRCD_SOCKETENGINE_NAME "@SOCKETENGINE@"
+
+#ifndef _WIN32
+ %target include/config.h
+ %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 c14099323..7610557b8 100644
--- a/make/template/inspircd
+++ b/make/template/inspircd
@@ -1,3 +1,4 @@
+%mode 0750
#!/usr/bin/env perl
#
@@ -30,7 +31,7 @@ my $runpath = "@BASE_DIR@";
my $datadir = "@DATA_DIR@";
my $valgrindlogpath = "$basepath/valgrindlogs";
my $executable = "inspircd";
-my $version = "@VERSION@";
+my $version = "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@+@VERSION_LABEL@";
my $uid = "@UID@";
if (!("--runasroot" ~~ @ARGV) && ($< == 0 || $> == 0)) {
diff --git a/make/template/main.mk b/make/template/main.mk
index e0018d728..9a8853021 100644
--- a/make/template/main.mk
+++ b/make/template/main.mk
@@ -1,3 +1,5 @@
+%target BSD_MAKE BSDmakefile
+%target GNU_MAKE GNUmakefile
#
# InspIRCd -- Internet Relay Chat Daemon
#
@@ -31,8 +33,8 @@
CXX = @CXX@
-COMPILER = @COMPILER@
-SYSTEM = @SYSTEM@
+COMPILER = @COMPILER_NAME@
+SYSTEM = @SYSTEM_NAME@
BUILDPATH ?= $(PWD)/build
SOCKETENGINE = @SOCKETENGINE@
CORECXXFLAGS = -fPIC -fvisibility-inlines-hidden -pipe -Iinclude -Wall -Wextra -Wfatal-errors -Wno-unused-parameter -Wshadow
@@ -50,11 +52,11 @@ INSTMODE_DIR = 0750
INSTMODE_BIN = 0750
INSTMODE_LIB = 0640
-@IFNEQ $(COMPILER) icc
+@IFNEQ $(COMPILER) ICC
CORECXXFLAGS += -pedantic -Woverloaded-virtual -Wshadow -Wformat=2 -Wmissing-format-attribute
@ENDIF
-@IFNEQ $(SYSTEM)-$(COMPILER) darwin-gcc
+@IFNEQ $(SYSTEM)-$(COMPILER) darwin-GCC
CORECXXFLAGS += -fvisibility=hidden
@ENDIF
@@ -88,7 +90,7 @@ INSTMODE_LIB = 0640
DBGOK=0
@IFEQ $(D) 0
CORECXXFLAGS += -O2
-@IFEQ $(CXX) g++
+@IFEQ $(COMPILER) GCC
CORECXXFLAGS += -g1
@ENDIF
HEADER = std-header
@@ -106,18 +108,18 @@ DBGOK=0
@ENDIF
FOOTER = finishmessage
-@GNU_ONLY MAKEFLAGS += --no-print-directory
+@TARGET GNU_MAKE MAKEFLAGS += --no-print-directory
-@GNU_ONLY SOURCEPATH = $(shell /bin/pwd)
-@BSD_ONLY SOURCEPATH != /bin/pwd
+@TARGET GNU_MAKE SOURCEPATH = $(shell /bin/pwd)
+@TARGET BSD_MAKE SOURCEPATH != /bin/pwd
@IFDEF V
RUNCC = $(CXX)
RUNLD = $(CXX)
VERBOSE = -v
@ELSE
- @GNU_ONLY MAKEFLAGS += --silent
- @BSD_ONLY MAKE += -s
+ @TARGET GNU_MAKE MAKEFLAGS += --silent
+ @TARGET BSD_MAKE MAKE += -s
RUNCC = perl $(SOURCEPATH)/make/run-cc.pl $(CXX)
RUNLD = perl $(SOURCEPATH)/make/run-cc.pl $(CXX)
@ENDIF
@@ -139,8 +141,8 @@ TARGET = all
@IFDEF M
HEADER = mod-header
FOOTER = mod-footer
- @BSD_ONLY TARGET = modules/${M:S/.so$//}.so
- @GNU_ONLY TARGET = modules/$(M:.so=).so
+ @TARGET BSD_MAKE TARGET = modules/${M:S/.so$//}.so
+ @TARGET GNU_MAKE TARGET = modules/$(M:.so=).so
@ENDIF
@IFDEF T
@@ -229,11 +231,11 @@ install: target
[ $(BUILDPATH)/modules/ -ef $(MODPATH) ] || $(INSTALL) -m $(INSTMODE_LIB) $(BUILDPATH)/modules/*.so $(MODPATH)
@ENDIF
-$(INSTALL) -m $(INSTMODE_BIN) inspircd $(BASE) 2>/dev/null
+ -$(INSTALL) -m $(INSTMODE_LIB) .gdbargs $(BASE)/.gdbargs 2>/dev/null
@IFEQ $(SYSTEM) darwin
-$(INSTALL) -m $(INSTMODE_BIN) org.inspircd.plist $(BASE) 2>/dev/null
@ENDIF
-$(INSTALL) -m $(INSTMODE_BIN) tools/genssl $(BINPATH)/inspircd-genssl 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
@@ -253,7 +255,7 @@ install: target
GNUmakefile BSDmakefile: make/template/main.mk src/version.sh configure .config.cache
./configure -update
-@BSD_ONLY .MAKEFILEDEPS: BSDmakefile
+@TARGET BSD_MAKE .MAKEFILEDEPS: BSDmakefile
clean:
@echo Cleaning...
diff --git a/make/template/org.inspircd.plist b/make/template/org.inspircd.plist
index 1a5ba5b62..ef5ef199b 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">
diff --git a/make/utilities.pm b/make/utilities.pm
index 9d791870a..404243966 100644
--- a/make/utilities.pm
+++ b/make/utilities.pm
@@ -36,19 +36,44 @@ use File::Spec::Functions qw(rel2abs);
use Getopt::Long;
use POSIX;
-our @EXPORT = qw(module_installed prompt_bool prompt_dir prompt_string get_cpu_count make_rpath pkgconfig_get_include_dirs pkgconfig_get_lib_dirs pkgconfig_check_version translate_functions promptstring);
+our @EXPORT = qw(get_version module_installed prompt_bool prompt_dir prompt_string get_cpu_count 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.
+my %already_added = ();
+my %version = ();
-# \e[1;32msrc/Makefile\e[0m
+sub get_version {
+ return %version if %version;
-my %already_added = ();
-my $if_skip_lines = 0;
+ # 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 );
+ }
-sub module_installed($)
-{
+ # 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]+)(?:-\d+-(\w+))?$/) {
+ $version{MAJOR} = $1 unless defined $version{MAJOR};
+ $version{MINOR} = $2 unless defined $version{MINOR};
+ $version{PATCH} = $3 unless defined $version{PATCH};
+ $version{LABEL} = $4 if defined $4;
+ }
+
+ # The user is using a stable release which does not have
+ # a label attached.
+ $version{LABEL} = 'release' unless defined $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' unless defined $version{MAJOR};
+ $version{MINOR} = '0' unless defined $version{MINOR};
+ $version{PATCH} = '0' unless defined $version{PATCH};
+
+ return %version;
+}
+
+sub module_installed($) {
my $module = shift;
eval("use $module;");
return !$@;