#!/usr/bin/env perl
#
# Copyright (C) 2001-2021 Graeme Walker <graeme_walker@users.sourceforge.net>
# 
# This program 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, either version 3 of the License, or
# (at your option) any later version.
# 
# 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/>.
# ===
#
# make2cmake
#
# Parses automake files throughout the source tree and generates
# simplistic cmake files for a unix build.
#
# Eg:
#   $ ./make2cmake
#   $ mkdir build
#   $ cd build
#   $ cmake -DCMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make ..
#   $ make VERBOSE=1
#
# See also: winbuild.pl
#

use strict ;
use Cwd ;
use FileHandle ;
use File::Find ;
use File::Basename ;
use File::Spec ;
use File::Copy ;
use lib dirname($0) ;
use AutoMakeParser ;
$AutoMakeParser::debug = 0 ;

# makefile conditionals
my %switches = (
	GCONFIG_BSD => 0 ,
	GCONFIG_GUI => 0 ,
	GCONFIG_ICONV => 0 ,
	GCONFIG_INSTALL_HOOK => 0 ,
	GCONFIG_INTERFACE_NAMES => 1 ,
	GCONFIG_MAC => 0 ,
	GCONFIG_PAM => 0 ,
	GCONFIG_TESTING => 0 ,
	GCONFIG_TLS_USE_BOTH => 0 ,
	GCONFIG_TLS_USE_MBEDTLS => 0 ,
	GCONFIG_TLS_USE_NONE => 0 ,
	GCONFIG_TLS_USE_OPENSSL => 1 ,
	GCONFIG_WINDOWS => 0 ,
) ;

# makefile expansion variables -- many are required but not relevant
my %vars = (
	top_srcdir => "." ,
	top_builddir => "." ,
	sbindir => "." ,
	mandir => "." ,
	localedir => "." ,
	e_spooldir => "/var/spool/emailrelay" ,
	e_docdir => "." ,
	e_initdir => "." ,
	e_bsdinitdir => "." ,
	e_rundir => "." ,
	e_icondir => "." ,
	e_examplesdir => "." ,
	e_libexecdir => "." ,
	e_pamdir => "." ,
	e_sysconfdir => "/etc" ,
	GCONFIG_WINDRES => "" ,
	GCONFIG_WINDMC => "" ,
	GCONFIG_QT_LIBS => "" ,
	GCONFIG_QT_CFLAGS => "" ,
	GCONFIG_QT_MOC => "" ,
	GCONFIG_TLS_LIBS => "-lssl -lcrypto" ,
	GCONFIG_STATIC_START => "" ,
	GCONFIG_STATIC_END => "" ,
	RPM_ARCH => "x86" ,
	RPM_ROOT => "rpm" ,
	VERSION => FileHandle->new("VERSION")->gets() ,
) ;

run_generate( "emailrelay" , \%switches , \%vars ) ;

# ==

sub create_cmake_file
{
	my ( $project , $m , $switches ) = @_ ;

	my $path = join( "/" , dirname($m->path()) , "CMakeLists.txt" ) ;

	print "cmake-file=[$path]\n" ;
	my $fh = new FileHandle( $path , "w" ) or die ;

	my $compile_options = "-std=c++11 -pthread" ;
	my $link_options = "-pthread" ;

	print $fh "# $path -- generated by $0\n" ;
	if( $project )
	{
		print $fh "cmake_minimum_required(VERSION 2.8.11)\n" ;
		print $fh "project($project)\n" ;
		print $fh "add_compile_options($compile_options)\n" ;
	}

	print $fh "\n" ;
	for my $subdir ( $m->subdirs() )
	{
		print $fh "add_subdirectory($subdir)\n" ;
	}

	my $definitions = join( " " , "G_UNIX=1" , $m->definitions() ) ;
	my $includes = join( " " , "." , ".." , $m->includes($m->top()) ) ;

	my @libraries = $m->libraries() ;
	for my $library ( @libraries )
	{
		my $sources = join( " " , $m->sources( $library ) ) ;

		( my $library_key = $library ) =~ s/\.a$// ; $library_key =~ s/^lib// ;
		print $fh "\n" ;
		print $fh "add_library($library_key $sources)\n" ;
		print $fh "target_include_directories($library_key PUBLIC $includes)\n" ;
		print $fh "target_compile_definitions($library_key PUBLIC $definitions)\n" ;
	}

	my @programs = $m->programs() ;
	for my $program ( @programs )
	{
		my $sources = join( " " , $m->sources( $program ) ) ;
		my $our_libs = join( " " , $m->our_libs( $program ) ) ;
		my $sys_libs = join( " " , $m->sys_libs( $program ) ) ;

		my $program_sources = join(" ",split(' ',"$sources")) ;
		my $program_includes = join(" ",split(' ',"$includes")) ;
		my $program_libs = join(" ",split(' ',"$our_libs $sys_libs")) ;

		print $fh "\n" ;
		print $fh "add_executable($program $program_sources)\n" ;
		print $fh "target_include_directories($program PUBLIC $program_includes)\n" ;
		print $fh "target_compile_definitions($program PUBLIC $definitions)\n" ;
		print $fh "target_link_libraries($program $link_options $program_libs)\n" ;
	}

	$fh->close() or die ;
}

sub create_cmake_files
{
	my ( $project , $switches , $vars ) = @_ ;

	my @makefiles = AutoMakeParser::readall( "." , $switches , $vars , 1 ) ;
	my $first = 1 ;
	for my $m ( @makefiles )
	{
		create_cmake_file( $first?$project:undef , $m , $switches ) ;
		$first = 0 ;
	}
}

sub run_generate
{
	my ( $project , $switches , $vars ) = @_ ;
	create_cmake_files( $project , $switches , $vars ) ;
	create_gconfig_header() ;
}

sub create_gconfig_header
{
	my $path = "src/gconfig_defs.h" ;
	if( ! -f $path )
	{
		my $fh = new FileHandle( $path , "w" ) or die ;
		$fh->close() or die ;
	}
}

