#!/usr/bin/env perl # # Copyright (C) 2001-2022 Graeme Walker # # 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 . # === # # make2cmake # # Parses the autoconf/automake artifacts throughout the source tree # in order to generates simplistic 'cmake' files. # # Eg: # $ CXXFLAGS="-X" ./configure --with-whatever # $ bin/make2cmake # $ mkdir build # $ cd build # $ cmake .. # $ make VERBOSE=1 # # The autoconf CXXFLAGS flow through to 'target_compile_options()' (etc) # directives in the 'CMakeLists' files; other autoconf options flow # through the 'config.status' file. # # 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 ConfigStatus ; use AutoMakeParser ; $AutoMakeParser::debug = 0 ; my $cfg_verbose = 1 ; my $cfg_project = "emailrelay" ; my $cs = new ConfigStatus( "config.status" ) ; my %switches = $cs->switches() ; my %vars = $cs->vars() ; my %qt_config = ( dirs => { "gui" => 1 } , targets => { "emailrelay-gui.real" => 1 } , ) ; $vars{top_srcdir} = "." ; $vars{top_builddir} = "." ; create_cmake_files( $cfg_project , \%switches , \%vars , \%qt_config ) ; create_empty_gconfig_header() ; # == sub create_cmake_file { my ( $project , $m , $switches , $vars , $qt_config ) = @_ ; my $path = join( "/" , dirname($m->path()) , "CMakeLists.txt" ) ; _log( "cmake-file=[$path]" ) ; my $fh = new FileHandle( $path , "w" ) or die ; my $link_options = $m->link_options() ; my $compile_options = $m->compile_options() ; $compile_options = join(" ",$compile_options,"-std=c++11") if( $compile_options !~ m/std=c++/ ) ; print $fh "# $path -- generated by $0\n" ; if( $project ) { print $fh "cmake_minimum_required(VERSION 3.12)\n" ; print $fh "project($project)\n" ; print $fh "add_compile_options($compile_options)\n" ; } if( exists $qt_config->{dirs}->{basename(dirname($m->path()))} ) { print $fh "\n" ; print $fh "find_package(Qt5 REQUIRED COMPONENTS Widgets Gui Core)\n" ; } print $fh "\n" if $m->subdirs() ; for my $subdir ( $m->subdirs() ) { print $fh "add_subdirectory($subdir)\n" ; } my $definitions = join( " " , $m->definitions() ) ; my $includes = join( " " , "." , ".." , $m->includes($m->base()) ) ; 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_compile_options($library_key PUBLIC $compile_options)\n" ; print $fh "target_include_directories($library_key PUBLIC $includes)\n" ; print $fh "target_compile_definitions($library_key PUBLIC $definitions)\n" ; print $fh "set_target_properties($library_key PROPERTIES AUTOMOC ON)\n" if exists $qt_config->{targets}->{$library_key} ; } 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_link_options($program PUBLIC $link_options)\n" ; # cmake 3.13 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 $program_libs)\n" ; print $fh "set_target_properties($program PROPERTIES AUTOMOC ON)\n" if exists $qt_config->{targets}->{$program} ; } $fh->close() or die ; } sub create_cmake_files { my ( $project , $switches , $vars , $qt_config ) = @_ ; my @makefiles = AutoMakeParser::readall( "." , $switches , $vars , $cfg_verbose , "make2cmake: " ) ; my $first = 1 ; for my $m ( @makefiles ) { create_cmake_file( $first?$project:undef , $m , $switches , $vars , $qt_config ) ; $first = 0 ; } } sub create_empty_gconfig_header { my $path = "src/gconfig_defs.h" ; if( ! -f $path ) { my $fh = new FileHandle( $path , "w" ) or die ; $fh->close() or die ; } } sub _log { print "make2cmake: " , @_ , "\n" if $cfg_verbose ; }