#!/usr/bin/perl -w # NAME: log2cmake.pl # AIM: Take a unix build log, and attempt to create a CMakeLists.txt from it, hopefully... # 21/09/2015 - add more compiler switches # 28/09/2014 - Need to FIX bug about 'duplicated' library names # 23/12/2013 - Some more tweaks using unix-bldlog.txt for gmp library # 25/10/2013 - If given a current base, use a full directory scan to search for source files # 02/10/2013 - Add -b base_directory used in log file # 27/08/2013 - Lots more work with different styles build log files, and fill out the cmake script # 20/08/2013 - gcc lines can be a compile or a link # 13/03/2013 geoff mclane http://geoffair.net/mperl use strict; use warnings; use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] ) use Cwd; my $os = $^O; my $perl_dir = '/home/geoff/bin'; my $PATH_SEP = '/'; my $temp_dir = '/tmp'; if ($os =~ /win/i) { $perl_dir = 'C:\GTools\perl'; $temp_dir = $perl_dir; $PATH_SEP = "\\"; } unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n"; # log file stuff our ($LF); my $pgmname = $0; if ($pgmname =~ /(\\|\/)/) { my @tmpsp = split(/(\\|\/)/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt"; open_log($outfile); # user variables my $VERS = "0.0.3 2015-09-21"; #my $VERS = "0.0.2 2013-08-27"; #my $VERS = "0.0.1 2013-03-13"; my $load_log = 0; my $in_file = ''; my $verbosity = 0; my $out_file = ''; my $base_dir = ''; my $src_dir = ''; my $proj_name = ''; my $tmp_out = $temp_dir.$PATH_SEP."tempCMakeLists.txt"; my $show_ignored = 0; my $show_finding = 0; my $min_source = 2; # if 2 or less, no new line my $skip_test_block = 1; # skip begin '`' until next # ### DEBUG ### my $db_shw_mhdrs = 0; my $debug_on = 0; my $def_file = 'C:\FG\18\ELFkickers\build\ELFkickers\bldlog-u.txt'; my $def_base = '/home/geoff/projects/ELFkickers'; my $def_src = "C:\\FG\\18\\ELFkickers"; #my $def_file = 'C:\FG\18\gettext-0.18.1.1\build\bldlog-u.txt'; #my $def_file = 'C:\FG\17\wget-1.14\bldlog-1.txt'; #my $def_base = '/home/geoff/projects/gettext-0.18.1.1'; #my $def_src = "C:\\FG\\18\\gettext-0.18.1.1"; ### program variables my @warnings = (); my $cwd = cwd(); my $curr_rel_dir = ''; my $curr_abs_dir = ''; my $chk_src_file = 0; my %entered_dirs = (); my $curr_lnn = 0; my $curr_tline = ''; my %comp_defines = (); sub VERB1() { return $verbosity >= 1; } sub VERB2() { return $verbosity >= 2; } sub VERB5() { return $verbosity >= 5; } sub VERB9() { return $verbosity >= 9; } sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { prt( "\nNo warnings issued.\n\n" ) if (VERB9()); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_log($outfile,$load_log); exit($val); } sub prtw($) { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } # ============================================== # 10/04/2012 - begin to process files with a BOM # LOAD without a BOM my $strip_bom = 1; my $curr_file_bom = ''; my @BOM_list = ( [ "UTF-8", 3, [0xEF,0xBB,0xBF ] ], # 239 187 191 [ "UTF-16 (BE)", 2, [0xFE,0xFF ] ], # 254 255 [ "UTF-16 (LE)", 2, [0xFF,0xFE ] ], # 255 254 [ "UTF-32 (BE)", 4, [0x00,0x00,0xFE,0xFF] ], # 0 0 254 255 [ "UTF-32 (LE)", 4, [0xFF,0xFE,0x00,0x00] ], # 255 254 0 0 [ "UTF-7a" , 4, [0x2B,0x2F,0x76,0x38] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F [ "UTF-7b" , 4, [0x2B,0x2F,0x76,0x39] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F [ "UTF-7c" , 4, [0x2B,0x2F,0x76,0x2B] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F [ "UTF-7d" , 4, [0x2B,0x2F,0x76,0x2F] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F [ "UTF-1" , 3, [0xF7,0x64,0x4C ] ], # 247 100 76 [ "UTF-EBCDIC" , 4, [0xDD,0x73,0x66,0x73] ], # 221 115 102 115 [ "SCSU" , 3, [0x0E,0xFE,0xFF ] ], # 14 254 255 [ "BOCU-1" , 3, [0xFB,0xEE,0x28 ] ], # 251 238 40 [ "GB-18030" , 4, [0x84,0x31,0x95,0x33] ] # 132 49 149 51 ); sub line_has_bom($$) { my ($line,$rname) = @_; my $max = scalar @BOM_list; my $len = length($line); my ($i,$j,$name,$cnt,$ra,$ch,$val); for ($i = 0; $i < $max; $i++) { $name = $BOM_list[$i][0]; # name $cnt = $BOM_list[$i][1]; # length $ra = $BOM_list[$i][2]; # ref array of values if ($len > $cnt) { # make sure line length GT BOM for ($j = 0; $j < $cnt; $j++) { $ch = substr($line,$j,1); # extract CHAR $val = ord($ch); # get VALUE last if ($val != ${$ra}[$j]); # compare } if ($j == $cnt) { # if ALL values found ${$rname} = $name; # give back 'name' return $cnt; # and return count } } } return 0; # no BOM found } sub remove_utf_bom($$) { my ($ff,$ra) = @_; my $line = ${$ra}[0]; # get first line my $name = ''; my $len = line_has_bom($line,\$name); if ($len) { $curr_file_bom = substr($line,0,$len); $line = substr($line,$len); # truncate line ${$ra}[0] = $line; # and return minus BOM my ($nm,$dr) = fileparse($ff); # just show name prt("[v9] NOTE: File [$nm] is $name encoding. BOM($len) removed.\n") if (VERB9()); } } sub load_file_lines($$) { my ($ff,$ra) = @_; my $lncnt = 0; $curr_file_bom = ''; if (open INF, "<$ff") { @{$ra} = ; close INF; $lncnt = scalar @{$ra}; remove_utf_bom($ff,$ra) if ($strip_bom); } else { prtw("WARNING: Unable to open [$ff]!\n"); } return $lncnt; } sub get_show_stg($) { my $txt = shift; my $len = length($txt); if ($len < 103) { return $txt; } my $ntxt = substr($txt,0,50); $ntxt .= "..."; $ntxt .= substr($txt,length($txt)-50); return $ntxt; } my @curr_srcs = (); sub mycmp_decend_aaa { # alpha sort - case insensitive return -1 if (lc(${$a}[0]) lt lc(${$b}[0])); return 1 if (lc(${$a}[0]) gt lc(${$b}[0])); return 0; } sub mycmp_decend_a { # alpha sort - case insensitive return -1 if (lc($a) lt lc($b)); return 1 if (lc($a) gt lc($b)); return 0; } sub strip_src_dir($) { my $dir = shift; my $len = length($src_dir); return $dir if ($len == 0); return $dir if (length($dir) < $len); my ($i); for ($i = 0; $i < $len; $i++) { if (substr($dir,$i,1) ne substr($src_dir,$i,1)) { prtw("WARNING: Failed match at $i on $len [$dir] [$src_dir]\n"); return $dir; } } $dir = substr($dir,$len); $dir =~ s/^(\\|\/)//; return $dir; } my @comp_switches = qw(-fdata-sections -ffunction-sections -fgnu89-inline -fomit-frame-pointer -freorder-blocks -include -pipe -pthread -Wall -Wcast-align -Wdeclaration-after-statement -Wempty-body -Werror=return-type -Wno-unused -Wpointer-arith -Wsign-compare -Wtype-limits -Woverloaded-virtual -Werror=conversion-null -Wno-invalid-offsetof -fno-rtti -fno-exceptions ); sub isInCompSw($) { my $txt = shift; my ($sw); foreach $sw (@comp_switches) { return 1 if ($txt =~ /^$sw/); } return 0; } sub strip_comp_line($$) { my ($txt,$rh) = @_; my @arr = space_split($txt); my @narr = (); my @csrcs = (); my $cnt = scalar @arr; my ($i,$tmp); my $comp = ''; for ($i = 0; $i < $cnt; $i++) { $txt = $arr[$i]; if (($txt eq 'gcc')||($txt eq 'g++')||($txt eq 'c++')) { $comp = $txt; next; } next if ($txt =~ /^-std=/); next if ($txt =~ /^-I/); next if ($txt =~ /^-fPIC/); next if ($txt =~ /^\d*>/); next if ($txt =~ /^-O/); next if ($txt =~ /^-g/); next if ($txt =~ /^-M/); next if ($txt =~ /^-fvis/); next if ($txt =~ /^-c/); next if ($txt =~ /^-o/); if ($txt =~ /^-D/) { $txt = substr($txt,2); $comp_defines{$txt} = 1; next; } next if (isInCompSw($txt)); if ($txt =~ /^-/) { prtw("Compile switch '$txt' not listed! ** FIX ME **\n"); next; } if ($txt eq '||') { last; } elsif ($txt eq '>') { last; } if ( ($txt =~ /^`test/) && (($i + 2) < $cnt) ) { # could be `test -f 'gettext.c' $tmp = $arr[$i+2]; $tmp =~ s/^\'//; $tmp =~ s/\'$//; if ( is_c_source($tmp) ) { $txt = $tmp; $i += 2; } #prt(join(" ",@arr)."\n"); #pgm_exit(1, "Got [$txt] [$tmp]\n"); } push(@narr,$txt); if ( is_c_source($txt) ) { push(@csrcs,$txt); if ($chk_src_file) { my $ff = $txt; my $ok = 'NOT FOUND'; ### prt("CHECK SOURCE [$txt]\n"); if (check_for_source($txt,\@curr_srcs,$curr_lnn,$curr_tline,\$ff,"strip_comp")) { $ok = 'ok'; } else { $ff = $txt; } #my $ff = fix_rel_path($curr_abs_dir.$PATH_SEP.$txt); #if (-f $ff) { # $ok = 'ok'; # $ff = strip_src_dir($ff); # push(@curr_srcs,$ff); #} #prt("SRC: $ff $ok\n"); ${$rh}{$ff} = $ok; } else { ${$rh}{$txt} = 1; } } } @csrcs = sort mycmp_decend_a @csrcs; $tmp = scalar @csrcs; prt("$curr_lnn: comp $comp: $tmp srcs - ".join(" ",@csrcs)."\n"); $txt = join(" ",@narr); return $txt; } sub strip_link_line($) { my $txt = shift; my @arr = space_split($txt); my @narr = (); foreach $txt (@arr) { next if ($txt =~ /^-std=/); next if ($txt =~ /^-D/); next if ($txt =~ /^-g$/); next if ($txt =~ /^-O/); next if ($txt eq '-lc'); next if ($txt =~ /^-Wl,/); next if ($txt =~ /^-shared/); next if ($txt =~ /^-L/); next if ($txt eq '-nostdlib'); push(@narr,$txt); } $txt = join(" ",@narr); return $txt; } sub strip_base_dir($) { my $dir = shift; my $len = length($base_dir); return $dir if ($len == 0); return $dir if (length($dir) < $len); my ($i); for ($i = 0; $i < $len; $i++) { if (substr($dir,$i,1) ne substr($base_dir,$i,1)) { prtw("WARNING: Failed match at $i on $len [$dir] [$base_dir]\n"); return $dir; } } $dir = substr($dir,$len); return $dir; } # if 'gcc -Wall ... -c -o dynamic.o dynamic.c' is COMPILE # gcc -M -g -O2 -DUSE_MODEL -I/usr/include geometry.c partibrains.c > Makedepend # if 'gcc ebfc.o brainfuck.o libelfparts.a -o ebfc' is LINK # c++ -o host_jskwgen -Wall -Wpointer-arith -Woverloaded-virtual -Werror=return-type # -Wtype-limits -Wempty-body -Werror=conversion-null -Wsign-compare -Wno-invalid-offsetof # -Wcast-align -fno-rtti -ffunction-sections -fdata-sections -fno-exceptions -pthread # -pipe -DNDEBUG -DTRIMMED -g -O3 -freorder-blocks -fomit-frame-pointer # -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1 -DENABLE_JIT=1 -I./../../mfbt/double-conversion # -I./../../intl/icu/source/common -I./../../intl/icu/source/i18n -I. -I. -I./dist/include # -I. -I./assembler -I./yarr host_jskwgen.o sub is_compile_line($) { my $line = shift; return 1 if (($line =~ /\s+-c\s+/)&&($line =~ /\s+-o\s+/)); # but sometimes there is NO output -o!!! like # gcc -c -g -O2 -W -Wall -std=c99 -pedantic -DHAVE_CONFIG_H -I. -I.. rdfdump.c] FIX ME return 1 if (($line =~ /\s+-c\s+/)&&($line =~ /\s+-std=/)); my @arr = space_split($line); my ($tmp,$cnt); $cnt = 0; foreach $tmp (@arr) { if (($tmp eq 'gcc')||($tmp eq 'g++')||($tmp eq 'c++')) { # should be first } elsif ($tmp =~ /^-/) { # is just a param } elsif ($tmp eq '>') { last; } else { if (is_c_source($tmp)) { $cnt++; } } } return 1 if ($cnt); return 0; } sub is_compile_lineo($) { my $line = shift; my @arr = space_split($line); my $last = $arr[-1]; return 1 if ($last =~ /\.o$/); return 0; } sub is_link_line($) { my $line = shift; return 0 if ($line =~ /\s+-c\s+/); return 1 if ($line =~ /\s+-o\s+/); return 0; } my @cfile_exts = qw( .c .cxx .cpp .cc ); my @hfile_exts = qw( .h .hxx .hpp ); my %done_txt = (); my $done_scan = 0; my $dirs_found = 0; my $files_found = 0; my %dir_scan = (); sub scan_directory($$); sub scan_directory($$) { my ($dir,$lev) = @_; if (! opendir(DIR,$dir) ) { prtw("WARNING: Failed to open directory $dir!\n"); return; # nothing to do but return } my @files = readdir(DIR); closedir(DIR); my ($file,$ff,$ra); ut_fix_directory(\$dir); my @dirs = (); $dirs_found++; foreach $file (@files) { next if ($file eq '.'); next if ($file eq '..'); $ff = $dir.$file; if (-d $ff) { push(@dirs,$ff); } elsif (-f $ff) { # keep everything, or just likely sources - no EVERYTHING # keep as hash or array - choose array, since can push full and file name # but a hash on file name with an array of locations seems best $dir_scan{$file} = [] if (!defined $dir_scan{$file}); $ra = $dir_scan{$file}; push(@{$ra},$dir); # this file was found in this array of directories $files_found++; } else { pgm_exit(1,"ERROR: WHAT IS THIS [$ff] if not file or folder!!! FIX ME!!!\n"); } } foreach $ff (@dirs) { scan_directory($ff,($lev+1)); } if ($lev == 0) { prt("In scan of $dirs_found Directories, found $files_found files...\n"); } } sub scan_base() { $done_scan = 1; scan_directory($src_dir,0); } sub find_this_file($$) { my ($fil,$rff) = @_; scan_base() if (!$done_scan); my ($ra,$hint,$ff); $hint = ${$rff}; if (defined $dir_scan{$fil}) { $ra = $dir_scan{$fil}; # TODO: for now take the first even if more than one $ff = ${$ra}[0]; # get the directory $ff .= $fil; # add the file if (-f $ff) { ${$rff} = $ff; return 1; } else { pgm_exit(1,"ERROR: A previously found file now NOT FOUND\nFile [$ff] FIX ME\n"); } } return 0; } my %shown_failed_find = (); sub check_for_source($$$$$$) { my ($txt_in,$ra,$lnn,$tline,$retff,$caller) = @_; my $ff = fix_rel_path($curr_abs_dir.$PATH_SEP.$txt_in); my $ok = 'NOT FOUND'; my ($tmp,$fil,$rff,@tried); my ($n,$d,$e); my ($name,$drv,$ext) = fileparse($txt_in, qr/\.[^.]*/); if (-f $ff) { $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); ${$retff} = $rff; # return source file found prt("$lnn:1: SRC: $rff $ok ($ff) [$txt_in]\n") if (VERB5()); ($n,$d,$e) = fileparse($ff, qr/\.[^.]*/); foreach $tmp (@hfile_exts) { #$fil = $d.$n.$tmp; $fil = $drv.$n.$tmp; $ff = fix_rel_path($curr_abs_dir.$PATH_SEP.$fil); $ok = 'NOT FOUND'; push(@tried,$ff); if (-f $ff) { $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); prt("$lnn:1: HDR: $rff $ok ($ff)\n") if (VERB5()); return 2; } } if (($db_shw_mhdrs || VERB9()) && !(defined $done_txt{$txt_in})) { prt("$lnn:1: NO HEADER for [$txt_in]! Tried\n"); prt(join("\n",@tried)."\n"); $done_txt{$txt_in} = 1; } return 1; } # ========================================================= # maybe it was a object source, with the .o or .lo stripped foreach $tmp (@cfile_exts) { $fil = $txt_in.$tmp; $ff = fix_rel_path($curr_abs_dir.$PATH_SEP.$fil); $ok = 'NOT FOUND'; if (-f $ff) { $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); ${$retff} = $rff; prt("$lnn:2: SRC: $rff $ok ($ff) [$txt_in]\n") if (VERB5()); ($n,$d,$e) = fileparse($ff, qr/\.[^.]*/); @tried = (); foreach $tmp (@hfile_exts) { ###$fil = $d.$n.$tmp; $fil = $drv.$n.$tmp; $ff = fix_rel_path($curr_abs_dir.$PATH_SEP.$fil); push(@tried,$ff); $ok = 'NOT FOUND'; if (-f $ff) { $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); prt("$lnn:2: HDR: $rff $ok ($ff)\n") if (VERB5()); return 2; } } if (($db_shw_mhdrs || VERB9()) && !(defined $done_txt{$txt_in})) { prt("$lnn:2: NO HEADER for [$txt_in]! Tried\n"); prt(join("\n",@tried)."\n"); } return 1; } } # ok, maybe $txt is the relative path, and all that is needed is add the source # ============================================================================= my $dir = $src_dir; # given by user ut_fix_directory(\$dir); $fil = $dir.$txt_in; if (-f $fil) { $rff = strip_src_dir($fil); push(@{$ra},$rff); ${$retff} = $rff; prt("$lnn:3: SRC: $rff $ok ($fil) [$txt_in]\n") if (VERB5()); ($n,$d,$e) = fileparse($fil, qr/\.[^.]*/); foreach $tmp (@hfile_exts) { $ff = $d.$n.$tmp; if (-f $ff) { $rff = strip_src_dir($ff); push(@{$ra},$rff); prt("$lnn:3: HDR: $rff $ok ($ff)\n") if (VERB5()); return 2; } } return 1; } foreach $tmp (@cfile_exts) { $ff = $fil.$tmp; $ok = 'NOT FOUND'; if (-f $ff) { $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); ${$retff} = $rff; prt("$lnn:2: SRC: $rff $ok ($ff) [$txt_in]\n") if (VERB5()); @tried = (); foreach $tmp (@hfile_exts) { $ff = $fil.$tmp; push(@tried,$ff); $ok = 'NOT FOUND'; if (-f $ff) { $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); prt("$lnn:2: HDR: $rff $ok ($ff)\n") if (VERB5()); return 2; } } if (($db_shw_mhdrs || VERB9()) && !(defined $done_txt{$txt_in})) { prt("$lnn:2: NO HEADER for [$txt_in]! Tried\n"); prt(join("\n",@tried)."\n"); } return 1; } } # 25/10/2013 - ok, all find methods FAILED, so scan the directory if givin a -source # ======================================================================================== if (length($src_dir)) { prt("Searching for [$txt_in] in scan...\n") if (VERB9()); if (find_this_file($txt_in,\$ff)) { # ok, found it in a base directory scan $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); ${$retff} = $rff; prt("$lnn:4: SRC: $rff $ok ($ff)\n") if (VERB5()); # now try to find a matching header file ($n,$d,$e) = fileparse($ff, qr/\.[^.]*/); foreach $tmp (@hfile_exts) { $ff = $d.$n.$tmp; if (-f $ff) { $rff = strip_src_dir($ff); push(@{$ra},$rff); prt("$lnn:4: HDR: $rff $ok ($ff)\n") if (VERB5()); return 2; } } return 1; } foreach $tmp (@cfile_exts) { my $tmp2 = $txt_in.$tmp; prt("Searching for [$tmp2] in scan...\n") if (VERB9() || $show_finding); if (find_this_file($tmp2,\$ff)) { # ok, found it in a base directory scan $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); ${$retff} = $rff; prt("$lnn:4: SRC: $rff $ok ($ff)\n") if (VERB5() || $show_finding); # now try to find a matching header file ($n,$d,$e) = fileparse($ff, qr/\.[^.]*/); foreach $tmp (@hfile_exts) { $ff = $d.$n.$tmp; if (-f $ff) { $rff = strip_src_dir($ff); push(@{$ra},$rff); prt("$lnn:4: HDR: $rff $ok ($ff)\n") if (VERB5() || $show_finding); return 2; } } return 1; } } if ($name.$ext ne $txt_in) { foreach $tmp (@cfile_exts) { my $tmp2 = $name.$tmp; prt("Searching for [$tmp2] in scan...\n") if (VERB9() || $show_finding); if (find_this_file($tmp2,\$ff)) { # ok, found it in a base directory scan $ok = 'ok'; $rff = strip_src_dir($ff); push(@{$ra},$rff); ${$retff} = $rff; prt("$lnn:4: SRC: $rff $ok ($ff)\n") if (VERB5() || $show_finding); # now try to find a matching header file ($n,$d,$e) = fileparse($ff, qr/\.[^.]*/); foreach $tmp (@hfile_exts) { $ff = $d.$n.$tmp; if (-f $ff) { $rff = strip_src_dir($ff); push(@{$ra},$rff); prt("$lnn:4: HDR: $rff $ok ($ff)\n") if (VERB5() || $show_finding); return 2; } } return 1; } } } } # ======================================================================================== ############################################################ ### NOT FOUND - WHY??????? if (defined $shown_failed_find{$txt_in}) { return 0; } $shown_failed_find{$txt_in} = 1; $ff = fix_rel_path($curr_abs_dir.$PATH_SEP.$txt_in); my $msg = "$lnn: $tline"; $msg .= "\nFull: $curr_tline" if ($tline ne $curr_tline); prtw("WARNING: $lnn: FAILED TO FIND SOURCE [$txt_in] [$ff] [$fil]\n$msg\ncaller=$caller\n"); ###pgm_exit(1,"TEMP EXIT"); return 0; } my %heads = (); my %funcs = (); my %types = (); sub process_checking($$) { my ($lnn,$inc) = @_; my ($itm,$msg,@arr,$cnt); @arr = split(/\s+/,$inc); $cnt = scalar @arr; if ($inc =~ /^for\s+(\S+)\.\.\./) { $itm = trim_all($1); $inc = trim_all(substr($inc,(4 + length($itm) + 3))); if (($inc =~ /yes/)||($inc =~ /no/)) { if ($itm =~ /\.h/) { $heads{$itm} = 1; $msg = 'H'; } elsif ($itm =~ /_t$/) { $types{$itm} = 1; $msg = 'T'; } else { $funcs{$itm} = 1; $msg = 'F'; } prt("$lnn: FOR $msg $itm RES Y/N\n") if (VERB9()); } else { prt("$lnn: FOR $itm RES $inc\n") if (VERB2()); } } elsif ( ($arr[0] =~ /\.h/ ) && ($cnt == 3) && (($arr[1] eq 'usability...')||($arr[1] eq 'presence...')) && (($arr[2] eq 'yes')||($arr[2] eq 'no')) ) { $heads{$arr[0]} = 1; } else { prt("$lnn: $inc\n") if (VERB2()); } } sub show_hdrs() { my ($cnt,$key,@arrh,$var,$minh,$len,$def,@defs,@arrf,$minf); @arrh = sort keys(%heads); @arrf = sort keys(%funcs); $minh = 0; foreach $key (@arrh) { $len = length($key); $minh = $len if ($len > $minh); } $minf = 0; foreach $key (@arrf) { $len = length($key); $minf = $len if ($len > $minf); } # headers $cnt = scalar @arrh; prt("\n# $cnt checks for headers\n"); @defs = (); foreach $key (@arrh) { $var = uc($key); $var =~ s/\./_/g; $var =~ s/\//_/g; $def = "#cmakedefine HAVE_$var 1"; push(@defs,$def); $key .= ' ' while (length($key) < $minh); prt(" check_include_file($key HAVE_$var)\n"); } prt("\n".join("\n",@defs)."\n"); # functions $cnt = scalar @arrf; prt("\n# $cnt checks for functions\n"); @defs = (); foreach $key (@arrf) { $var = uc($key); $var =~ s/\./_/g; $var =~ s/\//_/g; $def = "#cmakedefine HAVE_$var 1"; push(@defs,$def); $key .= ' ' while (length($key) < $minf); prt(" check_function_exists($key HAVE_$var)\n"); } prt("\n".join("\n",@defs)."\n"); } # split_space - space_split - # like split(/\s/,$txt), but honour double inverted commas # also accept and split '"something"/>', but ONLY if in the tail # 2010/05/05 - also want to avoid a tag of '"zlib">' sub my_space_split { my ($txt) = shift; my $len = length($txt); my ($k, $ch, $tag, $incomm, $k2, $nch); my @arr = (); $tag = ''; $incomm = 0; for ($k = 0; $k < $len; $k++) { $ch = substr($txt,$k,1); $k2 = $k + 1; $nch = ($k2 < $len) ? substr($txt,$k2,1) : ""; if ($incomm) { $incomm = 0 if ($ch eq '"'); $tag .= $ch; # add 2010/05/05 to avoid say '"zlib">' begin a tag if (!$incomm) { push(@arr,$tag); $tag = ''; } } elsif ($ch =~ /\s/) { # any spacey char push(@arr, $tag) if (length($tag)); $tag = ''; } elsif (($ch =~ /\//)&&($nch eq '>')) { # 04/10/2008, but only if before '>' 24/09/2008 add this as well push(@arr, $tag) if (length($tag)); $tag = $ch; # restart tag with this character } elsif ($skip_test_block && ($ch eq '`')) { $k++; for (; $k < $len; $k++) { $ch = substr($txt,$k,1); last if ($ch eq '`'); } } else { $tag .= $ch; $incomm = 1 if ($ch eq '"'); } } push(@arr, $tag) if (length($tag)); return @arr; } sub process_in_file($) { my ($inf) = @_; #if (! open INF, "<$inf") { # pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); #} #my @lines = ; #close INF; #my $lncnt = scalar @lines; my @lines = (); my $lncnt = load_file_lines($inf,\@lines); prt("Processing $lncnt lines, from [$inf]...\n"); my ($line,$inc,$lnn,$i,$tline,$len,$i2,$tmp,$dir,$ldir); my (@arr,$j,$alen,$lib,$ind,$blnn,$elnn,$oline); my ($off1,$off2,$sline,$cmd1); $lnn = 0; $dir = ''; $ldir = ''; my %hash = (); my $islink = 0; my $iscomp = 0; my %sources = (); my @dir_stack = (); # if we have BOTH a base directory and a current source directory, then we can check the source my $lbd = length($base_dir); my $lsd = length($src_dir); #$chk_src_file = ($lbd && $lsd) ? 1 : 0; $chk_src_file = ($lsd > 0) ? 1 : 0; for ($i = 0; $i < $lncnt; $i++) { $line = $lines[$i]; chomp $line; $lnn++; $curr_lnn = $lnn; $i2 = $i + 1; $tline = trim_all($line); $len = length($tline); next if ($len == 0); $blnn = $lnn; while (($tline =~ /\\$/)&&($i2 < $lncnt)) { $tline =~ s/\\$//; # remove $tline = trim_all($tline); $i++; $tmp = $lines[$i]; chomp $tmp; $lnn++; $i2 = $i + 1; $tline .= ' ' if (length($tline)); $tline .= trim_all($tmp); } $elnn = $lnn; $len = length($tline); #$ind = index($tline," && mv "); #if ($ind > 0) { # $tline = substr($tline,0,length($tline)-$ind); # $len = length($tline); #} # skip configure lines, but extract 'cmake' script from 'checking ...' lines if ($line =~ /^checking\s+/) { $line = substr($line, 9); process_checking($blnn,$line); next; } next if ($line =~ /^creating cache/); next if ($line =~ /^configure:\s/); next if ($line =~ /^config.status:\s+/); next if ($line =~ /^===\s+configuring/); next if ($line =~ /^\(cached\)\s+checking\s+/); next if ($line =~ /^defined\(\@array\) is/); next if ($line =~ /Maybe you should just/); next if ($line =~ /^\[master\s+/); next if ($line =~ /^WARNING:\s+/); next if ($line =~ /^if\s+test\s+/); $oline = $tline; $curr_tline = $tline; $islink = 0; $iscomp = 0; # but this can be a horrible line like - # cd tools/dev && /bin/bash /home/geoff/projects/subversion/subversion-1.8.1/libtool ... # gcc -g -O2 -pthread -rpath /usr/local/lib -o fsfs-reorg fsfs-reorg.lo # ../../subversion/libsvn_delta/libsvn_delta-1.la ../../subversion/libsvn_subr/libsvn_subr-1.la -lapr-1 # which is a link line, or # if false ; then /bin/bash /home/geoff/projects/subversion/subversion-1.8.1/libtool --tag=CC # --silent --mode=compile gcc -std=c90 -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -g -O2 -pthread # -I./subversion/include -I./subversion -I/usr/include/apr-1.0 -I/usr/include/apr-1.0 # -o subversion/mod_dav_svn/activity.lo -c subversion/mod_dav_svn/activity.c ; # else echo "fake" > subversion/mod_dav_svn/activity.lo ; fi # which is a compile of a source line, so make is SIMPLE if ($tline =~ /^if\s+(\S+)\s*;\s*then\s+/) { $tline =~ s/^if\s+(\S+)\s*;\s*then\s+//; } @arr = my_space_split($tline); $cmd1 = $arr[0]; $off1 = scalar @arr; $off2 = 0; if ($cmd1 =~ /bin\/python$/) { for ($j = 1; $j < $off1; $j++) { $cmd1 = $arr[$j]; if ($cmd1 eq 'ar') { #prt("Before '$tline'\n"); $tline = join(' ', splice(@arr,$j)); # get bal of line #prt("After '$tline'\n"); #pgm_exit(1,"TEMP EXIT\n"); $off2 = 1; last; } } next if ($off2 == 0); } $off1 = index($tline," gcc "); $off2 = index($tline," -o "); if (($off1 > 0) && ($off2 > $off1)) { $sline = substr($tline,0,$off1); # get head of line if ($sline =~ /^cd\s+(\S+)\s+&/) { $curr_rel_dir = $1; ut_fix_rpath_per_os(\$curr_rel_dir); $curr_abs_dir = fix_rel_path($src_dir.$PATH_SEP.$curr_rel_dir) if (length($src_dir)); ut_fix_rpath_per_os(\$curr_abs_dir); prt("$lnn: Enter abs $curr_abs_dir\n") if (VERB5()); ###pgm_exit(1,"TEMP EXIT: Entered [$curr_rel_dir] abs [$curr_abs_dir]\n"); } $tline = substr($tline,$off1 + 1); $off1 = index($tline,';'); if ($off1 > 0) { $tline = trim_all(substr($tline,0,$off1)); ###pgm_exit(1,"Is LINK or COMPILE [$tline]"); } } if ($tline =~ /^libtool:\s+link:\s+/) { $tline =~ s/^libtool:\s+link:\s+//; if (($tline =~ /^\s*\(\s*cd\s+/)&&($tline =~ /\s+rm\s+-f\s+/)) { next; } # libtool: link: gcc .libs/gettext-po.o .libs/str-list.o # -Wl,--whole-archive ./.libs/libgnu.a -Wl,--no-whole-archive -lc # -Wl,-soname -Wl,libgettextpo.so.0 -o .libs/libgettextpo.so.0.5.1 $tline = strip_link_line($tline); $islink = 1; } elsif ($tline =~ /^libtool:\s+compile:\s+/) { $tline =~ s/^libtool:\s+compile:\s+//; $tline = strip_comp_line($tline, \%sources); $iscomp = 1; } elsif (($tline =~ /^gcc\s+/)||($tline =~ /^g\+\+\s+/)) { # 20/08/2013 - gcc lines can be a compile or a link # if 'gcc -Wall ... -c -o dynamic.o dynamic.c' is COMPILE # if 'gcc ebfc.o brainfuck.o libelfparts.a -o ebfc' is LINK # gcc -M -g -O2 -DUSE_MODEL -I/usr/include geometry.c partibrains.c > Makedepend if (is_compile_line($tline)) { $tline = strip_comp_line($tline, \%sources); $iscomp = 1; # already check this - if ($tline =~ /\s+-c\s+/); } elsif (is_link_line($tline)) { $tline = strip_link_line($tline); $islink = 1; } else { prtw("WARNING: $blnn: Unknown 'gcc' line [$tline] FIX ME\n"); } } elsif ($tline =~ /^c\+\+ /) { if (is_compile_line($tline)) { $tline = strip_comp_line($tline, \%sources); $iscomp = 1; # already check this - if ($tline =~ /\s+-c\s+/); } elsif (is_compile_lineo($tline)) { # TODO: What to do wiht this? } else { pgm_exit(1,"ERROR:$lnn: Deal with compile line!\n$tline\n"); } } elsif ($tline =~ /^ar /) { $tline = strip_link_line($tline); $islink = 1; } next if ($tline =~ /^mv\s+/); next if ($tline =~ /^rm\s+/); next if ($tline =~ /^\s*\/bin\//); next if ($tline =~ /^\/usr\//); next if ($tline =~ /^Making\s+/); next if ($tline =~ /^ranlib /); next if ($tline =~ /^sed\s+/); ###next if ($tline =~ /^echo /); if ($tline =~ /^(-|\w)+\.\w+:/) { next; } if ($tline =~ /^make/) { if ($tline =~ / Entering directory `(.+)'/) { # \'(.+)\'/) { $tmp = $1; if ($tmp ne $dir) { $ldir = $dir; $dir = $tmp; $curr_rel_dir = strip_base_dir($dir); if ($chk_src_file) { push(@dir_stack,$curr_abs_dir) if (length($curr_abs_dir)); $curr_abs_dir = fix_rel_path($src_dir.$PATH_SEP.$curr_rel_dir); ut_fix_rpath_per_os(\$curr_abs_dir); prt("$lnn: Enter abs $curr_abs_dir\n") if (VERB5()); $entered_dirs{$curr_abs_dir} = 1; } else { prt("$lnn: Enter rel $curr_rel_dir\n") if (VERB5()); } } @curr_srcs = (); # clear compiled list on directory change } elsif ($tline =~ / Leaving directory `(.+)'/) { # \'(.+)\'/) { $tmp = $1; # leaving a directory apparently pops back to previous entered if (@dir_stack) { $curr_abs_dir = $dir_stack[-1]; pop @dir_stack; prt("$lnn: popped abs $curr_abs_dir\n") if (VERB5()); } if ($ldir ne $dir) { prt("$lnn: Exit $dir to $ldir\n") if (VERB9()); $dir = $ldir; } } next; } if ($islink) { ###@arr = split(/\s+/,$tline); @arr = my_space_split($tline); $alen = scalar @arr; my @a = (); $lib = 'NOT FOUND'; my ($n,$d,$typ,$ra,$ccnt); $typ = "UNKNOWN"; my %h = (); my @narr = (); # processing a LINK line, like # libtool: link: gcc -std=gnu99 -g -O2 -o .libs/msgfilter # msgfilter-msgfilter.o msgfilter-filter-sr-latin.o # ./.libs/libgettextsrc.so /home/geoff/projects/gettext-0.18.1.1/gettext-tools/gnulib-lib/.libs/libgettextlib.so # /usr/lib/x86_64-linux-gnu/libxml2.so -lc # 1 - preprocess, looking for -o output # 20141213: skip these lines # libtool: link: echo "{ global:" > .libs/libssh2.ver # libtool: link: cat .libs/libssh2.exp | sed -e "s/\(.*\)/\1;/" >> .libs/libssh2.ver my $fnd = 0; my $isar = 0; my $isln = 0; # create link, or copy, or echo usually for ($j = 0; $j < $alen; $j++) { $tmp = $arr[$j]; if (($tmp eq '-o')&&(($j + 1) < $alen)) { $j++; $tmp = $arr[$j]; ($lib,$d) = fileparse($tmp); if (!($lib =~ /\./)) { # no extension s- sure sign it is an $typ = 'EXE'; } elsif ($lib =~ /\.so(\s|\.)*/) { $typ = 'DLL'; $lib =~ s/\.so.*$//; } else { #$typ = 'EXE'; $typ = 'LIB'; } $fnd = 1; last; } elsif ($tmp eq 'ar') { $isar = 1; } elsif ($tmp eq 'ln') { $isln = 1; last; } elsif ($tmp eq 'echo') { $isln = 1; last; } elsif ($tmp eq 'cat') { $isln = 1; last; } } if ($isln) { prt("$lnn: Skipping link,copy,echo,cat [$tline]\n"); next; } my $isgcc = 0; my $isshared = 0; my $hasobjs = 0; my $objcnt = 0; if (!$fnd && !$isar) { # line like # libtool: link: gcc -std=gnu99 -shared -fPIC -DPIC .libs/assert.o .libs/compat.o # .libs/errno.o .libs/extract-dbl.o .libs/invalid.o .libs/memory.o .libs/mp_bpl.o # ...lots more object files... # mpf/.libs/mul_ui.o mpf/.libs/div.o mpf/.libs/div_ui.o mpf/.libs/cmp.o # mpf/.libs/cmp_d.o mpf/.libs/cmp_ui.o mpf/.libs/cmp_si.o mpf for ($j = 0; $j < $alen; $j++) { $tmp = $arr[$j]; if ($tmp eq 'libtool:') { } elsif ($tmp eq 'link:') { } elsif ($tmp eq 'gcc') { $isgcc = 1; } elsif ($tmp =~ /^-/) { if ($tmp eq '-shared') { $isshared++; $typ = 'DLL'; } elsif ($tmp eq '-fPIC') { $isshared++; $typ = 'DLL'; } } else { ($n,$d) = fileparse($tmp); if ($n =~ /\.o$/) { $objcnt++; if (check_for_source($tmp,\@a,$lnn,$tline,\$tmp,"new_serv")) { $hasobjs++; } } else { $lib = $tmp; } } } if ($isgcc && $objcnt && $isshared && length($lib)) { prt("$lnn: Got $objcnt objects, $hasobjs sources, name [$lib], shared $typ\n"); $fnd = 1; } else { prtw("WARNING: $lnn: New services did NOT work!\nline [$line]\n"); # exit(1); } } if (!$fnd) { if (!$isar) { ###prtw("WARNING: No -o found! CHECK LINE\n$oline\n"); pgm_exit(1,"EXIT: NOT ar, no -o found! CHECK LINE\n$oline\n*** FIX ME ***\n"); } # ar line like # libtool: link: ar cru .libs/libgnuintl.a bindtextdom.o dcgettext.o dgettext.o # gettext.o finddomain.o hash-string.o loadmsgcat.o localealias.o textdomain.o # l10nflist.o explodename.o dcigettext.o dcngettext.o dngettext.o ngettext.o # plural.o plural-exp.o localcharset.o threadlib.o lock.o relocatable.o # langprefs.o localename.o log.o printf.o setlocale.o version.o osdep.o # intl-compat.o # NOTE; for ($j = 0; $j < $alen; $j++) { $tmp = $arr[$j]; if ($tmp =~ /\.a$/) { ($lib,$d) = fileparse($tmp); $lib =~ s/\.a//; # the ARCHIVE LIBRARY NAME $typ = "LIB"; $fnd = 1; last; } elsif ($tmp =~ /\.la$/) { ($lib,$d) = fileparse($tmp); $lib =~ s/\.la//; # the ARCHIVE LIBRARY NAME $typ = "LIB"; $fnd = 1; last; } } if (!$fnd) { pgm_exit(1,"WARNING: Is ar but no .a ouput found! CHECK LINE\n$oline\nFIX ME\n"); } } if (!$isgcc) { for ($j = 0; $j < $alen; $j++) { $tmp = $arr[$j]; if ($tmp =~ /\.a$/) { if ($typ eq 'UNKNONW') { ($lib,$d) = fileparse($tmp); $lib =~ s/\.a//; # the LIBRARY $typ = "LIB"; } else { $h{deps} = [] if (!defined $h{deps}); $ra = $h{deps}; push(@{$ra},$tmp); } } elsif ($tmp =~ /\.o$/) { $tmp =~ s/\.o$//; if ($chk_src_file) { check_for_source($tmp,\@a,$lnn,$tline,\$tmp,"notgcc.o"); } else { push(@a,$tmp); } } elsif ($tmp =~ /\.lo$/) { $tmp =~ s/\.lo$//; if ($chk_src_file) { check_for_source($tmp,\@a,$lnn,$tline,\$tmp,"notgcc.lo"); } else { push(@a,$tmp); } } elsif (($tmp eq '-o')&&(($j + 1) < $alen)) { $j++; # aleady done } elsif ($tmp =~ /\.so$/) { ($tmp,$d) = fileparse($tmp); ###$tmp =~ s/\.so$//; $h{deps} = [] if (!defined $h{deps}); $ra = $h{deps}; push(@{$ra},$tmp); } elsif ($tmp =~ /\.a$/) { ($tmp,$d) = fileparse($tmp); ###$tmp =~ s/\.so$//; $h{deps} = [] if (!defined $h{deps}); $ra = $h{deps}; push(@{$ra},$tmp); } elsif (is_c_source($tmp)) { if ($chk_src_file) { check_for_source($tmp,\@a,$lnn,$tline,\$tmp,"notgcc.isc"); } else { push(@a,$tmp); } } } } # 25/10/2013 - but ar can be used to append sources # 20130805 - NEVER overwrite an existing entry my $unam = $lib; if (! $isar) { $d = 0; while (defined $hash{$unam}) { $d++; $unam = $lib.$d; } } $alen = scalar @a; $ccnt = scalar @curr_srcs; prt("$lnn: $unam srcs $ccnt objs $alen\n") if (VERB9()); if (($ccnt == 0) && $islink && $alen) { # could be a line like, where the ONLY source indication is '...o' # and library deppendencies can be ...a or makebe ...so # gcc ebfc.o brainfuck.o libelfparts.a -o ebfc @curr_srcs = @a; $ccnt = scalar @curr_srcs; } my @a2 = (); if ($ccnt) { my %dh = (); foreach $tmp (@curr_srcs) { if (!defined $dh{$tmp}) { $dh{$tmp} = 1; push(@a2,$tmp); } } # MAYBE add from object as well, but no DUPES foreach $tmp (@a) { if (!defined $dh{$tmp}) { $dh{$tmp} = 1; push(@a2,$tmp); } } ###$h{asrcs} = \@a2; $ccnt = scalar @a2; } if ($lib eq 'NOT FOUND') { prtw("WARNING: $lnn: $typ $unam with $alen ($ccnt) sources!\n"); } elsif ($typ eq 'UNKNOWN') { prtw("WARNING: $lnn: $typ $unam with $alen ($ccnt) sources!\n"); } elsif ($ccnt == 0) { prtw("WARNING: $lnn: $typ $unam with $alen items but NO SOURCES!\n"); } else { prt("$lnn: $typ $unam with $alen ($ccnt) sources.\n"); if ($isar && defined $hash{$lib}) { my $refh = $hash{$lib}; # get the previous my $refa = ${$refh}{srcs}; push(@{$refa},@a); # just ADD these sources my $refa2 = ${$refh}{asrcs}; push(@{$refa2},@a2); # just ADD these sources } else { $h{type} = $typ; $h{srcs} = \@a; $h{line} = $lnn; $h{name} = $unam; $h{asrcs} = \@a2; $hash{$unam} = \%h; } } @curr_srcs = (); # NO must clear compiled list whether linking library or exe ###next; } $tmp = get_show_stg($tline); $tmp = "link: $tmp" if ($islink); $tmp = "comp: $tmp" if ($iscomp); prt("$i2: $tmp\n") if (VERB5() || $show_ignored); } $tmp = scalar keys(%sources); prt("Collected a total of $tmp sources...\n"); return \%hash; } my %headers = (); # headers are only ever attached to one build object sub get_includes_block() { my $txt = < $min_source); foreach $src (@{$rsa}) { $src = path_d2u($src); if (is_h_source($src)) { if (!defined $headers{$src}) { $headers{$src} = 1; push(@hdrs,$src); } } else { if ($scnt > $min_source) { $cmake .= $indent2."$src\n"; } else { $cmake .= " $src"; # stay inline for small counts } } } if ($scnt > $min_source) { $cmake .= $indent2.")\n"; } else { $cmake .= " )\n"; # keep it compact } $hcnt = scalar @hdrs; if ($hcnt) { $cmake .= $indent1."set(\${name}_HDRS"; $cmake .= "\n" if ($hcnt > $min_source); foreach $src (@hdrs) { if ($hcnt > $min_source) { $cmake .= $indent2."$src\n"; } else { $cmake .= " $src"; # keep compact } } if ($hcnt > $min_source) { $cmake .= $indent2.")\n"; } else { $cmake .= " )\n"; # compact for small sources } $cmake .= $indent1."add_executable(\${name} \${\${name}_SRCS} \${\${name}_HDRS})\n"; } else { $cmake .= $indent1."add_executable(\${name} \${\${name}_SRCS})\n"; } $cmake .= $indent1."# set_target_properties(\${name} PROPERTIES COMPILE_FLAGS \"-DMONOLITH\")\n"; $cmake .= $indent1."target_link_libraries(\${name} \${add_LIBS} \${extra_LIBS})\n"; $cmake .= $indent1."if (WIN32)\n"; $cmake .= $indent2."set_target_properties(\${name} PROPERTIES DEBUG_POSTFIX d)\n"; $cmake .= $indent1."endif ()\n"; $cmake .= $indent1."list(APPEND add_EXES \${name})\n"; $cmake .= "\n"; } } $cmake .= "endif ()\n" if ($cnt); $cnt = scalar @missed; prt("List of $cnt MISSED - CHECK THESE...\n") if ($cnt); foreach $key (@missed) { $rh2 = ${$rh}{$key}; $name = "NOT FOUND"; if (defined ${$rh2}{name}) { $name = ${$rh2}{name}; } $type = 'UNKNOWN'; if (defined ${$rh2}{type}) { $type = ${$rh2}{type}; } $scnt = 0; if (defined ${$rh2}{asrcs}) { $rsa = ${$rh2}{asrcs}; $scnt = scalar @{$rsa}; } $lnn = "unk"; if (defined ${$rh2}{line}) { $lnn = ${$rh2}{line}; } #prt("$key with $cnt2 items... name $name, type $type, srcs $scnt"); prt("$lnn: $type $key ($name) srcs $scnt"); ###prt(join(" ",@keys2)); prt("\n"); $tsrcs += $scnt; } #prt("Total source $tsrcs\n"); my $nam = length($proj_name) ? $proj_name : "FIX_PROJECT_NAME"; my $txt = get_cmake_header($nam); $txt .= add_options_block('OFF'); $txt .= get_definitions_block(); $txt .= $cmake; $txt .= "\n# eof\n"; my $file = $tmp_out; $file = $out_file if (length($out_file)); rename_2_old_bak($file); # NEVER overwrite write2file($txt,$file); prt("CMake script written to $file\n"); } ######################################### ### MAIN ### parse_args(@ARGV); my $ref_hash = process_in_file($in_file); show_hdrs(); ref_hash_2_cmake($ref_hash); pgm_exit(0,""); ######################################## sub need_arg { my ($arg,@av) = @_; pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av); } sub parse_args { my (@av) = @_; my ($arg,$sarg); while (@av) { $arg = $av[0]; if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if (($sarg =~ /^h/i)||($sarg eq '?')) { give_help(); pgm_exit(0,"Help exit(0)"); } elsif ($sarg =~ /^v/) { if ($sarg =~ /^v.*(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/) { $verbosity++; $sarg = substr($sarg,1); } } prt("Verbosity = $verbosity\n") if (VERB1()); } elsif ($sarg =~ /^l/) { if ($sarg =~ /^ll/) { $load_log = 2; } else { $load_log = 1; } prt("Set to load log at end. ($load_log)\n") if (VERB1()); } elsif ($sarg =~ /^n/) { need_arg(@av); shift @av; $sarg = $av[0]; $proj_name = $sarg; prt("Set project name to [$proj_name].\n") if (VERB1()); } elsif ($sarg =~ /^o/) { need_arg(@av); shift @av; $sarg = $av[0]; $out_file = $sarg; prt("Set out file to [$out_file].\n") if (VERB1()); } elsif ($sarg =~ /^s/) { need_arg(@av); shift @av; $sarg = $av[0]; $src_dir = $sarg; prt("Set src directory to [$src_dir].\n") if (VERB1()); pgm_exit(1,"ERROR: Unable to locate dir [$src_dir]\n") if (! -d $src_dir); } elsif ($sarg =~ /^b/) { need_arg(@av); shift @av; $sarg = $av[0]; $base_dir = $sarg; prt("Set base directory to [$src_dir].\n") if (VERB1()); } elsif ($sarg =~ /^i/) { $show_ignored = 1; prt("Set to output ignored lines. ($show_ignored)\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n"); } } else { $in_file = $arg; prt("Set input to [$in_file]\n") if (VERB1()); } shift @av; } if ($debug_on) { prtw("WARNING: DEBUG is ON\n"); if (length($in_file) == 0) { $in_file = $def_file; prt("Set DEFAULT input to [$in_file]\n"); ###$load_log = 1; $base_dir = $def_base; $src_dir = $def_src; } } if (length($in_file) == 0) { pgm_exit(1,"ERROR: No input files found in command!\n"); } if (! -f $in_file) { pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n"); } } sub give_help { prt("$pgmname: version $VERS\n"); prt("Usage: $pgmname [options] in-file\n"); prt("Options:\n"); prt(" --help (-h or -?) = This help, and exit 0.\n"); prt(" --verb[n] (-v) = Bump [or set] verbosity. def=$verbosity\n"); prt(" --load (-l) = Load LOG at end. ($outfile)\n"); prt(" --out (-o) = Write output to this file.\n"); prt(" --base (-b) = Base directory to be stripped from make enter directory.\n"); prt(" --name (-n) = Set the project name.\n"); prt(" --src (-s) = Current source base directory.\n"); prt(" --ignored (-i) = Show ALL ignored lines. (def=$show_ignored)\n"); prt("\n"); prt("Note: to be able to verify the source before adding it to the CMakeLists.txt\n"); prt(" need to be given the base directory to strip from a make entered directory,\n"); prt(" making it releative, AND a current source directory to search for the source,\n"); prt(" to establish a new absolute path to the source.\n"); } # eof - template.pl