#!/usr/bin/perl

# WARNING: Don't edit this file unless it is the master copy in org.glite.lb
#
# For the purpose of standalone builds of lb/jobid/lbjp-common components
# it is copied on tagging 

# $Header$
#
# Copyright (c) Members of the EGEE Collaboration. 2004-2010.
# See http://www.eu-egee.org/partners/ for details on the copyright holders.
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

use Getopt::Long;
use POSIX qw(locale_h strftime);

my $default_url = 'http://scientific.zcu.cz/emi/${moduleName}';

my $pwd = `pwd`; chomp $pwd;
my $prefix = '/usr';
my $stagedir = undef;
my $root = $pwd.'/stage';
my $sysroot = '';
my $sysconfdir;
my $localstatedir;
my $os_type;
my $staged;
my $module='lb.logger-msg';
my $thrflavour = '';
my $nothrflavour = '';
my $mode = 'build';
my $help = 0;
my $listmodules;
my ($version, $force_version);
my $lb_tag = '';
my $lbjp_tag = '';
my $jp_tag = '';
my $jobid_tag = '';
my $libdir = getlibdir();
my $project = 'emi';
my $project_version;
my (%projects, %project);
my $debug = 0;
my $url = $default_url;
my $url_source;
my $docdir;
my $mysqlconfdir;
my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : '';

my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal canl/;
my @default_nodes = qw/lb px proxyrenewal nagios canl client-java/;
my %enable_nodes;
my %disable_nodes;
my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1);

my %package = (
	'maintainer' => 'CESNET Product Teams <emi-lb@metacentrum.cz>',
	'uploaders' => 'František Dvořák <valtri@civ.zcu.cz>',
	'url' => 'http://glite.cern.ch',
	'debian_vcs' => 'Vcs-Cvs: :pserver:anonymous@jra1mw.cvs.cern.ch:/cvs/jra1mw
Vcs-Browser: http://jra1mw.cvs.cern.ch/cgi-bin/jra1mw.cgi',
);

# key:      internal package name (arguments, ...)
# 'pkg':    pkg-config name
# 'prefix': used when pkg-config fails
my %externs = (
	cares => {
		prefix => '/opt/c-ares',
		pkg => 'libcares'
	},
	classads => {
		prefix=> '/usr',
		pkg => 'classads'
	},
	cppunit => {
		prefix=> '/usr',
		pkg => 'cppunit'
	},
	expat => {
		prefix=> '/usr',
		pkg => 'expat'
	},
	globus => {
		prefix=> '/opt/globus',
		pkg => 'globus-gssapi-gsi'
	},
	'myproxy-devel' => {
		prefix=> '/opt/globus',
		pkg => 'myproxy'
	},
	'myproxy-server' => {
		prefix=> '',
	},
	'myproxy-admin' => {
		prefix=> '',
	},
	gsoap => {
		prefix=> '/usr',
		pkg => 'gsoap'
	},
	gsoapxx => {
		prefix=> '/usr',
		pkg => 'gsoap++'
	},
	mysql => {
		prefix=> '/usr'
	},
	'mysql-devel' => {
		prefix=> ''
	},
	'mysql-server' => {
		prefix => ''
	},
	voms => {
		prefix => '/usr',
		pkg => 'voms-2.0'
	},
	gridsite => {
		prefix => '/usr',
		pkg => 'gridsite-openssl'
	},
	trustmanager => {
		prefix => '/usr'
	},
	trustmanager_axis => {
		prefix => '/usr'
	},
	utiljava => {
		prefix=> '/opt/glite'
	},
	ant => {
		prefix=> '/usr'
	},
	jdk => {
		prefix=> '/usr/java/latest',
		locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ],
	},
	libtar => {
		prefix=> '/usr'
	},
	axis => {
		prefix=> '/usr'
	},
	log4c => {
		prefix=> '/usr'
	},
	postgresql => {
		prefix=> '/usr'
	},
	activemq => {
		prefix=>'/opt/activemq-cpp-library',
		pkg => 'activemq-cpp'
	},
	crypto => {
		prefix => '/usr',
		pkg => 'libcrypto',
	},
);

my %jar = (
	'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar',
	'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar',
);


my %glite_prefix;
my %need_externs;
my %need_externs_type;
my %need_jars;
my %extrafull;
my %extranodmod;
my %deps;
my %deps_type;
my %buildroot;

#
# modules of the subsystems
#
# additional modules from $project{modules} are automatically added
#
my %lbmodules = (
	'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], 
	'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/],
	'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/],
	'jp' => [ qw/client doc index primary server-common ws-interface/ ],
	'gridsite' => [ qw/apache libs commands core devel services service-clients/ ],
	'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ],
	'canl' => [ qw/c c-devel/ ],
	);

#
# sub-packages
#
# modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly
#
my %subpackages = (
	'jobid.api-c-devel' => 'jobid.api-c',
	'jobid.api-cpp-devel' => 'jobid.api-cpp',
	'lbjp-common.db-devel' => 'lbjp-common.db',
	'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin',
	'lbjp-common.gss-devel' => 'lbjp-common.gss',
	'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface',
	'lbjp-common.log-devel' => 'lbjp-common.log',
	'lbjp-common.maildir-devel' => 'lbjp-common.maildir',
	'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones',
	'lbjp-common.trio-devel' => 'lbjp-common.trio',
	'lb.client-progs' => 'lb.client',
	'lb.client-devel' => 'lb.client',
	'lb.common-devel' => 'lb.common',
	'lb.logger-devel' => 'lb.logger',
	'lb.state-machine-devel' => 'lb.state-machine',
	'px.proxyrenewal-devel' => 'px.proxyrenewal',
	'px.proxyrenewal-progs' => 'px.proxyrenewal',
	'canl.c-devel' => 'canl.c',
	'gridsite.apache' => 'gridsite.core',
	'gridsite.shared' => 'gridsite.core',
	'gridsite.commands' => 'gridsite.core',
	'gridsite.devel' => 'gridsite.core',
	'gridsite.libs' => 'gridsite.core',
	'gridsite.services' => 'gridsite.core',
	'gridsite.service-clients' => 'gridsite.core',
);

my @opts = (
	'prefix:s' => \$prefix,
	'staged=s' => \$staged,
	'module=s' => \$module,
	'thrflavour:s' => \$thrflavour,
	'nothrflavour:s' => \$nothrflavour,
	'mode=s' => \$mode,
	'listmodules=s' => \$listmodules,
	'version=s' => \$force_version,
	'stage=s' => \$stagedir,
	'root:s' => \$root,
	'sysroot:s' => \$sysroot,
	'sysconfdir=s' => \$sysconfdir,
	'localstatedir=s' => \$localstatedir,
	'os-type=s' => \$os_type,
	'lb-tag=s' => \$lb_tag,
	'lbjp-common-tag=s' => \$lbjp_tag,
	'jp-tag=s' => \$jp_tag,
	'jobid-tag=s' => \$jobid_tag,
	'canl-tag=s' => \$canl_tag,
	'px-tag=s' => \$px_tag,
	'help' => \$help,
	'libdir=s' => \$libdir,
	'project=s' => \$project,
	'debug' => \$debug,
	'url=s' => \$url,
	'url-source=s' => \$url_source,
	'docdir=s' => \$docdir,
	'mysqlconfdir=s' => \$mysqlconfdir,
);

for (@nodes) {
	$enable_nodes{$_} = 0;
	$disable_nodes{$_} = 0;
	
	push @opts,"disable-$_",\$disable_nodes{$_};
	push @opts,"enable-$_",\$enable_nodes{$_};
}

push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs;
push @opts,"with-$_=s",\$jar{$_} for keys %jar;

my @keeparg = @ARGV;

GetOptions @opts or die "Errors parsing command line\n";
$prefix=~s/\/$//;
$root=~s/\/$//;
$sysroot=~s/\/$//;
if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; }
if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; }
$sysconfdir=~s/\/$//;
$localstatedir=~s/\/$//;
if (not $os_type) { $os_type = os_type(); }
if (not $url_source) { $url_source = $url; }
$url=~s/\/$//;
$url_source=~s/\/$//;

$externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq '';
$externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq '';
$externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq '';

$externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq '';
$externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq '';
$externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq '';

if ($project =~ /^([^0-9]*)(.*)$/) {
	$project = $1;
	$project_version = $2;
}
%project = %{$projects{$project}};
$project_version = $project{current_version} unless $project_version;
if ($project ne 'emi' or $project_version <= 1) {
	$lbmodules{'gridsite'} = [ qw/apache shared commands core devel services service-clients/ ];
}
for $_ (keys %{$project{need_externs_aux}}) {
	$need_externs_aux{$_} = $project{need_externs_aux}{$_};
}
for my $ext (keys %need_externs_aux) {
	for (@{$need_externs_aux{$ext}}) {
		my ($pkg, $type) =/([^:]*)(?::(.*))?/;
		$type = 'BR' unless ($type);

		push @{$need_externs{$ext}},$pkg;
		$need_externs_type{$ext}->{$pkg} = $type;
	}
}
if ($project eq 'emi') {
	$extranodmod{lb} = 'lb.emi-lb';
	$extranodmod{px} = 'px.emi-px';
}
if ($project ne 'emi' or $project_version <= 2) {
	$project{modules}{gridsite} = [ qw/slashgrid gsexec/ ];
}
for $_ (keys %{$project{modules}}) {
	push @{$lbmodules{$_}},@{$project{modules}{$_}};
}


if ($help) { usage(); exit 0; }

if ($listmodules) {
	my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name};
	my @m;

	if (exists $lbmodules{$listmodules}) {
		@m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}};
	} else {
		if ($project eq 'emi' and $project_version == 1 and $listmodules ne 'gridsite.core') {
			# no sub-packages in EMI-1
		} else {
			for my $sub (keys %subpackages) {
				push @m, $sub if ($subpackages{$sub} eq $listmodules);
			}
		}
	}
	print map $_ eq "" ? "" : "$_ ", @m;
	print "\n";
	exit 0;
}

my $en;
for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; }

my $dis;
for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; }

die "--enable-* and --disable-* are mutually exclusive\n"
	if $en && $dis;

die "--module cannot be used with --enable-* or --disable-*\n"
	if $module && ($en || $dis);

die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}};

if ($dis) {
	for (@nodes) {
		$enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_});
	}
}

if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } };

for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; }

$stagedir = $root unless $stagedir;
$stagedir=~s/\/$// if ($stagedir);

if ($mode eq 'build') { for my $ext (keys %externs) {
	if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; }
	elsif (defined $externs{$ext}{pkg}) {
		my ($flag, $env, $cmd, $ret);
		my $pkg = $externs{$ext}{pkg};
		my $flagname = uc $externs{$ext}{pkg};
		$flagname =~ s/-[0-9\.]*$//;
		$flagname =~ y/-\+/_X/;

		print "Checking $pkg ... ";
		$env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig";
		$cmd = "$env pkg-config $pkg --exists >/dev/null";
		`$cmd`; $ret = $?;
		print "('$cmd' => $ret)\n" if ($debug);
		if ($ret == 0) {
			$externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`;
			chomp $externs{$ext}{prefix};
			print "$externs{$ext}{prefix}\n";

			$flag=`$env pkg-config $pkg --cflags`;
			$externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag);
			$flag=`$env pkg-config $pkg --libs`;
			$externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag);
		} else {
			print "(using default $externs{$ext}{prefix})\n";
		}
		print "\n" if ($debug);
	}
	elsif ($ext eq 'jdk') {
		my $jdk_prefix;

		print "Looking for some caffein ... ";
		if (defined($ENV{'JDK_HOME'}) and -f "$ENV{'JDK_HOME'}/include/jni.h") {
			$jdk_prefix = $ENV{'JDK_HOME'};
			print "JDK_HOME=$jdk_prefix\n";
		} elsif (defined($ENV{'JAVA_HOME'}) and -f "$ENV{'JAVA_HOME'}/include/jni.h") {
			$jdk_prefix = $ENV{'JAVA_HOME'};
			print "JAVA_HOME=$jdk_prefix\n";
		} else {
			foreach my $i (0..$#{$externs{$ext}{locations}}) {
				if (-e $externs{$ext}{locations}[$i] and -f "$externs{$ext}{locations}[$i]/include/jni.h") {
					$jdk_prefix=$externs{$ext}{locations}[$i];
					print "(found directory $jdk_prefix)\n";
					last;
				}
			}
			print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix);
		}
		$externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix);
	}
} }

if ($mode eq 'build') {
	print "Writing config.status\n";
	open CONF,">config.status" or die "config.status: $!\n";
	for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') {
		print CONF "$_=$ENV{$_} " if (defined $ENV{$_});
	}
	print CONF "$0 @keeparg\n";
	close CONF;
}


my @modules;
my %aux;

if ($module) {
#	push @modules,split(/[,.]+/,$module);
	push @modules,$module;
}
else {
	@modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes));
	
	my $n;

	do {
		local $"="\n";
 		$n = $#modules;
		push @modules,(map @{$deps{$_}},@modules);

		undef %aux; @aux{@modules} = (1) x ($#modules+1);
		@modules = keys %aux;
	} while ($#modules > $n);
}

@aux{@modules} = (1) x ($#modules+1);
delete $aux{$_} for (split /,/,$staged);
@modules = keys %aux;

mode_build() if $mode eq 'build';
mode_checkout() if $mode eq 'checkout';

sub mode_build {
	print "\nBuilding modules: @modules\n";
	print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n";
	
	my @ext = map @{$need_externs{$_}},@modules;
	my @myjars = map @{$need_jars{$_}},@modules;
	undef %aux; @aux{@ext} = 1;
	@ext = keys %aux;
	undef %aux; @aux{@myjars} = (1) x ($#myjars+1);
	@myjars = keys %aux;
	
	print "\nRequired externals:\n";
	print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext;
	print "\t$_: $jar{$_}\n" for @myjars;
	for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } };
	print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n";

	mkinc($_) for @modules;

	if ($module) {
		print "Not creating summary Makefile\n" if $debug;
	} else {
		print "Creating Makefile\n";

		open MAK,">Makefile" or die "Makefile: $!\n";

		print MAK "all: @modules\n\n";
		print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n";
		print MAK "clean check install dist distcheck rpm deb:\n";

		for (@modules) {
			my $full = full($_);
			print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n"
		}

		print MAK "\ndistclean:\n";

		for (@modules) {
			my $full = full($_);
			print MAK $buildroot{$_} eq '' ?
				"\tcd $full && \${MAKE} distclean\n" :
				"\trm -rf $full/$buildroot{$_}\n"
		}

		print MAK "\n";

		for (@modules) {
			my %ldeps; undef %ldeps;
			@ldeps{@{$deps{$_}}} = 1;
			for my $x (split /,/,$staged) { delete $ldeps{$x}; }
			my @dnames = $module ? () : keys %ldeps;
			my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage';

			my $full = full($_);
			my $build = $buildroot{$_};

			print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n";
			print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n";
		}

		print MAK qq/release-rpm: clean dist distcheck rpm

release-deb: clean dist distcheck deb

.PHONY: all stage clean check install dist distcheck rpm deb release-rpm release-deb
/;

		close MAK;
	}
}
	
sub mode_checkout() {
	for (@modules) {
		my $module = $_;
		my $tag = "";
		if ($lb_tag){
			for (@{$lbmodules{lb}}){
				if ("lb.".$_ eq $module){
					$tag = '-r '.$lb_tag;
				}
			}	
		}
		if ($lbjp_tag) {
			for (@{$lbmodules{'lbjp-common'}}){
				if ("lbjp-common.".$_ eq $module){
                                        $tag = '-r '.$lbjp_tag;
                                }
			}
		}
		if ($jp_tag){
			for (@{$lbmodules{'jp'}}){
	                        if ("jp.".$_ eq $module){
                                        $tag = '-r '.$jp_tag;
	                        }
                        }
		}
		if ($jobid_tag){
			for (@{$lbmodules{jobid}}){
				if ("jobid.".$_ eq $module){
                                        $tag = '-r '.$jobid_tag;
                                }
			}
		}
		if ($canl_tag) {
			for (@{$lbmodules{'canl'}}){
				if ("canl.".$_ eq $module){
                                        $tag = '-r '.$canl_tag;
                                }
			}
		}
		if ($px_tag) {
			for (@{$lbmodules{'px'}}){
				if ("px.".$_ eq $module){
                                        $tag = '-r '.$px_tag;
                                }
			}
		}
		#if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){
		#	print "found";
		#}
		$_ = full($_);
		print "\n*** Checking out $_\n";
		system("cvs checkout  $tag $_") == 0 or die "cvs checkout $tag $_: $?\n";
	}
}

BEGIN{
%need_externs_aux = (
	'lb.client' => [ qw/cppunit:B classads:B libtool:B globus:B pkgconfig:B/ ],
	'lb.common' => [ qw/expat cares:B cppunit:B classads:B libtool:B globus:B pkgconfig:B/ ],
	'lb.doc' => [ qw/tetex-latex:B texlive-latex-recommended:B texlive-fonts-recommended:B texlive-latex-extra:B/ ],
	'lb.logger' => [ qw/cppunit:B libtool:B globus:B pkgconfig:B/ ],
	'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B pkgconfig:B/ ],
	'lb.nagios' => [ qw/globus_proxy_utils:R/ ],
	'lb.server' => [ qw/globus_essentials:R globus:B expat cares mysql-server:R cppunit:B gsoap:B classads:B voms:B gridsite:B bison:B libtool:B libxml2 flex:B pkgconfig:B/ ],
	'lb.state-machine' => [ qw/classads:B libtool:B libxslt:B expat:B globus:B pkgconfig:B/ ],
	'lb.utils' => [ qw/cppunit:B libtool:B globus:B pkgconfig:B/ ],
	'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ],
	'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B pkgconfig:B/ ],
	'lb.types' => [ qw// ],
	'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B pkgconfig:B/ ],
	'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B pkgconfig:B/ ],
	'lbjp-common.log' => [ qw/log4c libtool:B/ ],
	'lbjp-common.maildir' => [ qw/libtool:B/ ],
	'lbjp-common.server-bones' => [ qw/libtool:B/ ],
	'lbjp-common.trio' => [ qw/cppunit:B libtool:B pkgconfig:B/ ],
	'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B pkgconfig:B/ ],
	'lbjp-common.gss' =>  [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B pkgconfig:B/ ],
	'lbjp-common.gsoap-plugin' =>  [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B pkgconfig:B/ ],
	'jobid.api-c' =>  [ qw/cppunit:B libtool:B crypto:B pkgconfig:B/ ],
	'jobid.api-cpp' =>  [ qw// ],
	'jobid.api-java' =>  [ qw/ant:B jdk:B/ ],
	'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B pkgconfig:B/ ],
        'jp.doc' => [],
        'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R pkgconfig:B/ ],
        'jp.primary' => [ qw/classads:B gsoap libtar globus_essentials:R globus:B  mysql-server:R pkgconfig:B/ ],
        'jp.server-common' => [],
        'jp.ws-interface' => [],
	'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B libxml2:B openssl:B doxygen:B pkgconfig:B libtool:B/ ],
	'gridsite.commands' => [ qw/curl:R openssl:R/ ],
	'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ],
	'gridsite.libs' => [ qw/libxml2:R openssl:R/ ],
	'gridsite.shared' => [ qw/libxml2:R openssl:R/ ],
	'gridsite.devel' => [ qw// ],
	'gridsite.slashgrid' => [ qw/curl:R fuse:R/],
	'gridsite.services' => [ qw/curl:R gsoap:R/ ],
	'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ],
	'gridsite.gsexec' => [ qw// ],
	'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ],
	'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B pkgconfig:B/ ],
	'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec
	'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B pkgconfig:B tetex-latex:B texlive-latex-recommended:B texlive-fonts-recommended:B texlive-latex-extra:/ ],
);

%need_jars = (
	'jobid.api-java' => [ qw/jakarta-commons-codec/ ],
	'lb.client-java' => [ qw/jakarta-commons-lang/ ],
);

for my $jar (keys %need_jars) {
	for (@{$need_jars{$jar}}) {
		$need_externs_type{$jar}->{$_} = 'BR'; 	# XXX
	}
}

%deps_aux = (
	'lb.client' => [ qw/
		lb.types:B lb.common
		lbjp-common.trio
		jobid.api-cpp:B jobid.api-c
		lbjp-common.gss
	/ ],
	'lb.client-java' => [ qw/
		lb.types:B
		lb.ws-interface:B
		jobid.api-java
	/ ],
	'lb.common' => [ qw/
		jobid.api-cpp:B jobid.api-c
		lb.types:B lbjp-common.trio lbjp-common.gss
	/ ],
	'lb.doc' => [ qw/lb.types:B/ ],
	'lb.logger' => [ qw/
		lbjp-common.trio
		lbjp-common.log
		jobid.api-c
		lb.common
		lbjp-common.gss
	/ ],
	'lb.logger-msg' => [ qw/
		lb.logger:B
	/ ],
	'lb.nagios' => [ qw/
		lb.client:R
		lb.ws-test:R
		lb.utils:R
	/ ],
	'lb.server' => [ qw/
		lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R
		lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log
		jobid.api-c
		lbjp-common.gsoap-plugin lbjp-common.gss
	/ ],
	'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ],
	'lb.utils' => [ qw/
		lbjp-common.jp-interface
		jobid.api-c
		lbjp-common.trio lbjp-common.maildir
		lb.client lb.state-machine lb.types:B
	/ ],
	'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface/ ],
	'lb.ws-interface' => [ qw/lb.types:B/ ],
	'lb.types' => [ qw// ],
	'lb.harvester' => [ qw/
		jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client
		lbjp-common.gss lbjp-common.log
	/ ],
	'lb.yaim' => [ qw// ],
	'lb.glite-LB' => [ qw/
		lb.logger:R lb.server:R lb.utils:R lb.doc:R
		lb.ws-test:R lb.harvester:R lb.yaim:R
		lb.logger-msg:R
	/ ],
	'lb.emi-lb' => [ qw/
		lb.logger:R lb.server:R lb.utils:R lb.doc:R
		lb.ws-test:R lb.harvester:R lb.yaim:R
		lb.logger-msg:R
	/ ],
	'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ],
	'lbjp-common.maildir' => [ qw// ],
	'lbjp-common.log' => [ qw// ],
	'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ],
	'lbjp-common.trio' => [ qw// ],
	'lbjp-common.gss' =>  [ qw// ],
	'lbjp-common.gsoap-plugin' =>  [ qw/lbjp-common.gss/ ],
	'jobid.api-c' =>  [ qw// ],
	'jobid.api-cpp' =>  [ qw/jobid.api-c/ ],
	'jobid.api-java' =>  [ qw// ],

	'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ],

	'jp.client' => [ qw/
                jp.ws-interface
                lbjp-common.jp-interface lbjp-common.maildir
                jobid.api-c
                lbjp-common.gsoap-plugin
        / ],
	'jp.doc' => [ qw// ],
	'jp.index' => [ qw/
                jp.server-common jp.ws-interface
                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
                lbjp-common.gsoap-plugin
        / ],
	'jp.primary' => [ qw/
                jobid.api-c
                jp.server-common jp.ws-interface
                lb.state-machine
                lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones
                lbjp-common.gsoap-plugin
        / ],
	'jp.server-common' => [ qw/ 
                lbjp-common.jp-interface lbjp-common.db
        / ],
	'jp.ws-interface' => [ qw// ],

	'gridsite.core' => [ qw/canl.c:B/ ],
	'gridsite.commands' => [ qw/gridsite.core:B/ ],
	'gridsite.apache' => [ qw/gridsite.core:B/ ],
	'gridsite.libs' => [ qw/gridsite.core:B / ],
	'gridsite.shared' => [ qw/gridsite.core:B / ],
	'gridsite.devel' => [ qw/gridsite.core:B/ ],
	'gridsite.slashgrid' => [ qw/gridsite.core:B/],
	'gridsite.services' => [ qw/gridsite.core:B/ ],
	'gridsite.service-clients' => [ qw/gridsite.core:B/ ],
	'gridsite.gsexec' => [ qw/gridsite.core:B/ ],

	'px.proxyrenewal' => [ qw// ],
	'px.glite-PX' => [qw/px.myproxy-yaim:R/],
	'px.emi-px' => [qw/px.myproxy-yaim:R/],
	'px.myproxy-yaim' => [ qw// ],
	'px.myproxy-config' => [],

	'canl.c' => [],

	# sub-packages (virtual ETICS components depending on the main)
	'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ],
	'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ],
	'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ],
	'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ],
	'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ],
	'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ],
	'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ],
	'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ],
	'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ],
	'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ],
	'lb.client-progs' => [ qw/lb.client:B/ ],
	'lb.client-devel' => [ qw/lb.client:B/ ],
	'lb.common-devel' => [ qw/lb.common:B/ ],
	'lb.logger-devel' => [ qw/lb.logger:B/ ],
	'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ],
	'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ],
	'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ],
	'canl.c-devel' => [ qw/canl.c:B/ ],
);

for my $ext (keys %deps_aux) {
	for (@{$deps_aux{$ext}}) {
		/([^:]*)(?::(.*))?/;
		push @{$deps{$ext}},$1;
		my $type = $2 ? $2 : 'BR';
		$deps_type{$ext}->{$1} = $type;
	}
}


%extrafull = (
	gridsite=>'org.gridsite.core',
	'canl.c' => 'emi.canl.canl-c',
	'canl.c-devel' => 'emi.canl.canl-c',
	'jobid.api-c-devel' => 'org.glite.jobid.api-c',
	'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp',
	'lbjp-common.db-devel' => 'org.glite.lbjp-common.db',
	'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin',
	'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss',
	'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface',
	'lbjp-common.log-devel' => 'org.glite.lbjp-common.log',
	'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir',
	'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones',
	'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio',
	'lb.client-devel' => 'org.glite.lb.client',
	'lb.client-progs' => 'org.glite.lb.client',
	'lb.common-devel' => 'org.glite.lb.common',
	'lb.logger-devel' => 'org.glite.lb.logger',
	'lb.state-machine-devel' => 'org.glite.lb.state-machine',
	'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal',
	'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal',
);

#( java => 'client-java' );
%extranodmod = (
	db => 'lbjp-common.db',
	jpprimary => 'jp.primary',
	jpindex => 'jp.index',
	jpclient => 'jp.client',
	lb => 'lb.glite-LB',
	px => 'px.glite-PX',
	proxyrenewal => 'px.proxyrenewal',
	canl => 'canl.c',
);

%obsoletes = (
	'lb.yaim' => [ qq/glite-yaim-lb/ ],
	'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ],
	'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ],
	'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec
	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
);

%conflicts = (
);

%provides = (
	'lbjp-common.gss' => [ qq/glite-security-gss/ ],
	'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ],
	'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ],
);

%cvs_prefix = (
	'lb' => 'org.glite',
	'jp' => 'org.glite',
	'jobid' => 'org.glite',
	'lbjp-common' => 'org.glite',
	'gridsite' => 'org',
	'px' => 'org.glite',
	'canl' => 'emi',
);

%cvs_tag_prefix = (
	'lb' => 'glite-',
	'jp' => 'glite-',
	'jobid' => 'glite-',
	'lbjp-common' => 'glite-',
	'gridsite' => '',
	'px' => 'glite-',
	'canl' => 'emi-',
);

%cvs_tag_suffix = (
	'lb' => '',
	'jp' => '',
	'jobid' => '',
	'lbjp-common' => '',
	'gridsite' => '-core',
	'px' => '',
	'canl' => '',
);


# ==== projects specification ====
# etics_name ........... ETICS project name
# tag_prefix ........... VCS tag prefix
# local_prefix ......... prefix (relative to stage)
# need_externs_aux ..... project-specific external dependencies
# modules .............. additional modules in subsystems
%projects = (
	glite => {
		current_version => 3,
		etics_name => 'org.glite',
		tag_prefix => { %cvs_tag_prefix },
		tag_suffix => { %cvs_tag_suffix },
		flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}',
		local_prefix => '',
		need_externs_aux => {
			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ],
			'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ],
			'lb.yaim' => [ qw/yaim_core:R/ ],
			'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/],
			'px.myproxy-yaim' => [ qw/yaim_core:R/ ],
		},
		modules => {
			'lb' => [ qw/glite-LB/ ],
			'px' => [ qw/glite-PX/ ],
		},
	},

	emi => {
		current_version => 3,
		etics_name => 'emi',
		tag_prefix => { %cvs_tag_prefix },
		tag_suffix => { %cvs_tag_suffix },
		flavours => '--thrflavour= --nothrflavour=',
		local_prefix => '/usr',
		need_externs_aux => {
			'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ],
			'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ],
			'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
			'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/],
			'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ],
		},
		modules => {
			'lb' => [ qw/emi-lb/ ],
			'px' => [ qw/emi-px/ ],
		},
	},
);

%platform_properties = (
	'jobid.api-cpp' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'jobid.api-java' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'lb.types' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'lb.doc' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'lb.ws-interface' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'lb.yaim' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'lb.nagios' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'px.yaim' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'px.myproxy-config' => {
		default => { 'package.buildarch' => 'noarch' },
	},
	'gridsite.devel' => {
		default => { 'packageName' => 'gridsite-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' },
	},
	'canl.c-devel' => {
		default => { 'packageName' => 'canl-c-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' },
	},
	'jobid.api-c-devel' => {
		default => { 'packageName' => 'glite-jobid-api-c-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' },
	},
	'jobid.api-cpp-devel' => {
		default => { 'packageName' => 'glite-jobid-api-cpp-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' },
	},
	'lbjp-common.db-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-db-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' },
	},
	'lbjp-common.gsoap-plugin-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' },
	},
	'lbjp-common.gss-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-gss-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' },
	},
	'lbjp-common.jp-interface-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' },
	},
	'lbjp-common.log-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-log-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' },
	},
	'lbjp-common.maildir-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-maildir-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' },
	},
	'lbjp-common.server-bones-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' },
	},
	'lbjp-common.trio-devel' => {
		default => { 'packageName' => 'glite-lbjp-common-trio-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' },
	},
	'lb.client-devel' => {
		default => { 'packageName' => 'glite-lb-client-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' },
	},
	'lb.common-devel' => {
		default => { 'packageName' => 'glite-lb-common-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' },
	},
	'lb.state-machine-devel' => {
		default => { 'packageName' => 'glite-lb-state-machine-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' },
	},
	'lb.logger-devel' => {
		default => { 'packageName' => 'glite-lb-logger-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' },
	},
	'px.proxyrenewal-devel' => {
		default => { 'packageName' => 'glite-px-proxyrenewal-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' },
	},
	'canl.c-devel' => {
		default => { 'packageName' => 'canl-c-devel' },
		deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' },
	},
);

my @k = keys %deps_aux;
@buildroot{@k} = ('') x ($#k+1);

$buildroot{'gridsite.core'} = 'src';
}

sub full
{
	my ($short) = @_;
	my $subsys = $short;
	$subsys =~ s/\..*//;

	my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite';
	return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short";
}

sub get_version
{
	my ($fmod, $top_srcdir) = @_;

	my ($subsys,$mod) = split /\./,$fmod,2;
	my ($major,$minor,$rev,$age);
	my $old_;

	if ($force_version) {
		$force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/;
		($major,$minor,$rev,$age) = ($1,$2,$3,$4);
	}
	else {
		my $path = "$top_srcdir/project";
		if ($subsys eq 'gridsite') {
			$path = "$cvs_prefix{$subsys}.$subsys.core/project";
		}
		open V,"$path/version.properties"
			or die "$path/version.properties: $!\n";

		$old_ = $_;
		while (<V>) {
			chomp;
			($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/;
			$age = $1 if /module\.age\s*=\s*(\S+)/;
		}
		close V;
		$_ = $old_;
	}
	$version = "$major.$minor.$rev-$age";

	return ($major, $minor, $rev, $age);
}

sub get_description
{
	my ($top_srcdir) = @_;

	my $cvs_module = $top_srcdir;
	my $package_description = "";
	my $package_summary = "";

	if (-e "$cvs_module/project/package.description") {
		open V, "$cvs_module/project/package.description";
		$package_description = join ("", <V>);
		close V;
		chomp $package_description;
	}
	else {
		print STDERR "package.description not found for $subsys.$module!\n"; }

	if (-e "$cvs_module/project/package.summary") {
		open V, "$cvs_module/project/package.summary";
		$package_summary = join ("", <V>);
		close V;
		chomp $package_summary;
		$package_summary =~ s/\n/\\n/g;
	}
	else {
		print STDERR "package.summary not found for $subsys.$module!\n"; }

	return ($package_summary, $package_description);
}

sub mkinc
{
	my %aux;
	undef %aux;
	my @m=qw/
lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb
lbjp-common.gss lbjp-common.gsoap-plugin
jobid.api-c jobid.api-cpp jobid.api-java
lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin
jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface
px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px
canl.c
/;
	@aux{@m} = (1) x ($#m+1);

	my ($short) = @_;
	my $full = full $short;
	my ($subsys,$mod) = split /\./,$short,2;
	my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}";

	unless ($aux{$short}) {
		print "Makefile.inc not needed in $full\n";
		return;
	}

	my $top_srcdir = '.';
	my $abs_srcdir = '';
	my $build = '';

	if ($module) {
		$top_srcdir = $0;
		$top_srcdir =~ s,/?[^/]*$,,;
		$abs_srcdir = $top_srcdir;
		$top_srcdir =~ s,^$,\.,;
	} else {
		$build = "$full/";
		$abs_srcdir = "$full/";
		unless ($buildroot{$_} eq '') {
			$top_srcdir = '..';
			$build .= "$buildroot{$_}/";
			unless (-d "$build") {
				mkdir "$build" or die "mkdir $build: $!\n";
			}
		}
	}

	my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir;
	my ($package_summary, $package_description) = get_description $abs_srcdir;
	if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; }
	my $package_description_debian = $package_description;
	$package_description_debian =~ s/^/ /mg;

	my ($old_locale, $specdate, $debdate);

	$old_locale = setlocale(LC_TIME);
	setlocale(LC_TIME, "C");
	$specdate = strftime("%a %b %d %Y", gmtime());
	$debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime());
	setlocale(LC_TIME, $old_locale);

	unless ($top_srcdir eq '.') {
		unlink $build."Makefile";
		symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n";
	}

	# package name
	my $dh;
	opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!";
	for my $dir (readdir $dh) {
		if ($dir=~/^(.*)\.spec$/) {
			if ($1 ne $packageName) {
				printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);;
				$packageName=$1;
			}
			last;
		}
	}
	closedir $dh;

	open MKINC,">".$build."Makefile.inc"
		or die $build."Makefile.inc: $!\n";

	print "Creating ".$build."Makefile.inc\n";

	print MKINC qq{project = $project
PREFIX = $root
prefix = $prefix
stagedir = $stagedir
sysroot = $sysroot
sysconfdir = $sysconfdir
localstatedir = $localstatedir
os_type = $os_type
thrflavour = $thrflavour
nothrflavour = $nothrflavour
libdir = $libdir
top_srcdir = $top_srcdir
};
	if ($docdir) {
		my $d = $docdir;
		$d =~ s/\$\{prefix\}/$prefix/g;
		$d =~ s/\$\{moduleName\}/$full/g;
		$d =~ s/\$\{packageName\}/$packageName/g;
		$d =~ s/\$\{version\}/$major.$minor.$rev/g;
		$d =~ s/\$\{age\}/$age/g;
		print MKINC "docdir = $d\n";
	}
	if ($mysqlconfdir) {
		print MKINC "mysqlconfdir = $mysqlconfdir\n";
	}

	for (@{$need_externs{$short}}) {
		next unless defined $externs{$_} and defined $externs{$_}{prefix};
		print MKINC "${_}_prefix = $externs{$_}{prefix}\n";
		print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags};
	}

	for (@{$need_jars{$short}}) {
		print MKINC "${_}_jar = $jar{$_}\n"
	}

	my $need_gsoap = 0;
	for (@{$need_externs{$short}})  { $need_gsoap = 1 if $_ eq 'gsoap'; }

	print MKINC "gsoap_default_version=".gsoap_version()."\n"  if $need_gsoap;

	print MKINC '
-include ${top_srcdir}/project/version.properties
version=${module.version}

${package}-${version}.tar.gz:
	rm -rf dist
	for dist in ${SOURCES} ${SOURCES_EXEC} configure project/ChangeLog project/debian.* project/*.spec project/package.* project/version.properties LICENSE; do \
		dir=${package}-${version}/`dirname $$dist`; \
		mkdir -p dist/$$dir || :; \
		install -m 0644 ${top_srcdir}/$$dist dist/$$dir; \
	done
	for dist in ${SOURCES_EXEC} configure; do \
		chmod +x dist/${package}-${version}/$$dist; \
	done
	(cd dist; tar -czf ${package}-${version}.tar.gz ${package}-${version})
	mv dist/${package}-${version}.tar.gz .

dist: ${package}-${version}.tar.gz

distcheck: ${package}-${version}.tar.gz
	rm -rf dist
	mkdir -p dist
	cp ${package}-${version}.tar.gz dist
	(cd dist; tar -xzf ${package}-${version}.tar.gz)
	a=`(cd dist/${package}-${version}; find . -type f | sort)`; \
	b=`(cd ${top_srcdir}; find . -path ./dist -prune -or -type f -print | sort)`; \
	echo "$$a" >dist/files-dist; \
	echo "$$b" | egrep -v "(^./Makefile.inc$$|^./${package}-${version}.tar.gz$$|^./debian|^./[^/]*.spec$$|\.cvsignore|^\./project/changelog$$|/CVS|^\./\.git|^\./config\.status$$)" >dist/files-original
	diff -U0 dist/files-dist dist/files-original

rpm: ${package}-${version}.tar.gz
	dir=dist/rpm_build_src; \
	rm -rf $$dir; \
	mkdir -p $$dir/BUILD $$dir/RPMS $$dir/SOURCES $$dir/SRPMS; \
	cp ${package}-${version}.tar.gz $$dir/SOURCES/${package}-${version}.tar.gz && \
	rpmbuild -bs --nodeps --define "_topdir $$dir" ${package}.spec && \
	cp -v $$dir/SRPMS/*.src.rpm dist/

deb: ${package}-${version}.tar.gz
	dir=dist/dpkg_build_src; \
	rm -rf $$dir; \
	mkdir -p $$dir; \
	cp ${package}-${version}.tar.gz $$dir/${package}_${version}.orig.tar.gz && \
	tar zxf $$dir/${package}_${version}.orig.tar.gz -C $$dir && \
	cp -rf debian/ $$dir/${package}-${version} && \
	(cd $$dir/${package}-${version} && dpkg-buildpackage -S -d -nc -us -uc) && \
	cp -v $$dir/*.tar.gz $$dir/*.dsc dist/
';

	close MKINC;

	my $debian = 0;

	for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") {
		if (-f "$abs_srcdir/project/$file") {
			my $old_ = $_;
			my $url_spec = $url_source;

			$url_spec =~ s/\$\{moduleName\}/$project{etics_name}.$subsys.$mod/g;
			$url_spec =~ s/\$\{packageName\}/%{name}/g;
			$url_spec =~ s/\$\{version\}/%{version}/g;
			$url_spec =~ s/\$\{age\}/%{rel}/g;

			printf STDERR "Creating $build$file\n" if ($debug);;
			open DST, ">$build$file";
			open SRC, "<$abs_srcdir/project/$file";
			while (<SRC>) {
				if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; }
				if (/\@PACKAGE_NAME\@/) { s/\@PACKAGE_NAME\@/$packageName/g; }
				if (/\@URL\@/) { s/\@URL\@/$package{url}/g; }
				if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; }
				if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; }
				if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; }
				if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; }
				if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; }
				if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; }
				if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; }
				if (/\@AGE\@/) { s/\@AGE\@/$age/g; }
				if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; }
				if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; }
				if (/\@DEBIAN_VCS\@/) { s/\@DEBIAN_VCS\@/$package{debian_vcs}/g; }
				if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; }
				if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; }
				if (/^\s*.+\/configure\s/ and $force_version) {
					print "Version forced to $version\n" if ($debug);;
					s/--version\s+\S+\s?//;
					s/$/ --version $version/;
				}
				if (/^Source:.*/ and $file =~ /\.spec$/) { s,^(Source:\s*).*?([^/]*)$,\1$url_spec/\2,; }
				printf DST "%s", "$_";
			}
			close SRC;
			close DST;
			$_ = $old_;
		}
	}

	if ($module and -d $build."debian") {
		print "Skipping ${build}debian/ (no rewrite in single module mode)\n" if ($debug);
		`rm -f ${build}debian.*`;
	} else {
		print "Creating ${build}debian/\n" if ($debug);;

		`rm -rfv  ${build}debian`;
		mkdir $build."debian" or die $!;
		`cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`;
		`mv ${build}debian.* ${build}debian/ 2>/dev/null`;
		`rm -f ${build}debian/*.orig`;
		opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!";
		for $_ (readdir $dh) {
			if (/^debian\.(.*)/) {
				`mv ${build}debian/$_ ${build}debian/$1`;
				$debian = 1;
			}
		}
		closedir $dh;

		if ($debian) {
			my ($dir, $file);

			chmod 0755, "${build}debian/rules";
			$file="${build}debian/docs"; if (not -f $file) { `touch $file`; }
			$dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; }
			$file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` }
			$file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` }
			$file="${build}debian/changelog"; if (not -f $file) {
				open FH, ">$file" or die $!;
				print FH qq{$packageName ($major.$minor.$rev-$age) stable; urgency=low

  * Automatically generated package

 -- $package{maintainer}  $debdate
};
				close FH;
			}

		} else {
			`rm -rf ${build}debian`;
		}
	}
}

BEGIN{
};

sub gsoap_version {
	local $_;
	my $gsoap_version;
	open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n";

	while ($_ = <S>) {
		chomp;

		$gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/;
		$gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/;
	}
	close S;
	return $gsoap_version;
}

sub getlibdir {
	if ( -e "/etc/debian_version") { # We are on Debian
		$lib64="lib";
		$lib32="lib32";	}
	else { # Another distribution
		$lib64="lib64";
		$lib32="lib";	}
        $libdir=$lib32;

        open INP, "uname -s | "; # Check kernel name
        $kname= <INP>;
        chomp($kname);
        close INP;

        if ( $kname eq "Linux") {
                $arch = ("x86_64\npowerpc\nppc64\n");

                open INP, "uname -p | "; # Check processor type
                $procname= <INP>;
                chomp($procname);
                close INP;

                if ($arch =~/^$procname\n/) {
                        return ($lib64); }

                open INP, "uname -m | "; # Check machine hardware
                $machname= <INP>;
                chomp($machname);
                close INP;

                if ($arch =~/^$machname\n/) {
                        return ($lib64); }

                # special cases (hyperlink lib64, Debian)
                if (-l "/usr/lib64") {
                        $libdir=$lib32; }

                # if /usr/lib64 doesn't exist at all (AIX)
                unless ( -e "/usr/lib64" ) {
                        $libdir=$lib32; }
        }

        if ( $kname eq "SunOS") {
                if (-e "/usr/lib/64") {
                $libdir="lib/64"; }
        }

        return $libdir;
}

sub os_type {
	my $ver;

	open FH, '<', '/etc/issue' or return "redhat";
	$_=<FH>;
	close FH;

	if (/Debian|Ubuntu/i) { return "debian"; }
	elsif (/Scientific|Redhat|Red Hat|Centos|Fedora/i) {
		`pkg-config --exists systemd`;
		if ($? == 0) { return "fedora"; }
		else { return "redhat"; }
	} else { return "redhat"; }
}

sub usage {
	my @ext = keys %externs;
	my @myjars = keys %jar;

	print STDERR qq{
Usage: $0 options

General options (defaults in []):
  --prefix=PREFIX		destination directory [./stage]
  --stage=DIR			staging directory [./stage]
  --root=DIR			installation root (custom relocation root -> sysroot) [./stage]
  --sysroot=DIR			system root (custom relocation root -> sysroot) []
  --sysconfdir=DIR              system configuration directory [PREFIX/etc]
  --localstatedir=DIR           system local status directory [PREFIX/var]
  --docdir			documentation directory []
  --mysqlconfdir		MySQL/MariaDB configuration directory []
  --os-type=DIST                system type (debian/redhat/fedora)
  --staged=module,module,...	what is already in PREFIX (specify without org.glite.)
  --thrflavour=flavour
  --nothrflavour=flavour	threaded and non-treaded flavours []
  --listmodules=subsys          list modules of a subsystem
  --listmodules=module          list subpackages of a module
  --version=maj.min.rev-age	version used instead of reading version.properties
  --libdir=libdir		typically [lib,lib64] postfix
  --project=PROJECT		build for a project (glite/emi1/emi) [emi]
  --debug			print more details
  --url				URL of all published files [$default_url]
  --url-source			URL of published source tarballs []
  
Mode of operation:
  --mode=\{checkout|build\}	what to do [build]
  
What to build:
  --module=module		build this module only
  --enable-NODE			build this "node" (set of modules) only
  --disable-NODE		don't build this node
  --lb-tag=tag			checkout LB modules with specific tag
  --jp-tag=tag			checkout JP modules with specific tag
  --lbjp-common-tag=tag         checkout lbjp-common modules with specific tag
  --jobid-tag=tag		checkout jobid modules with specific tag
  --canl-tag=tag		checkout canl modules with specific tag
  --px-tag=tag			checkout px modules with specific tag

Dependencies (summary of what will be used is always printed):
  --with-EXTERNAL=PATH		where to look for an external [autodetect]
  --with-JAR=JAR		where to look for jars

Available nodes:
    @nodes

Default nodes:
    @default_nodes

Externals (not all for all modules) are:
    @ext

External jars are:
    @myjars

};

}
