#!/usr/bin/perl -w # NAME: chkcmake.pl # AIM: Given an input folder, or input file, follow the CMakeLists.txt files # 26/04/2012 - If there exists a folder 'CMakeModules' load ALL from here - # It SEEMS these are AVAILABLE whether a specific 'INCLUDE(modulename)' or NOT is given! # 22/04/2012 - Some improvements... # 2012-01-29 - Run in Ubuntu and Windows # 25/10/2011 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"; require 'lib_cmakeread.pl' or die "Unable to load 'lib_cmakeread.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.4 2012-04-26"; # load ALL 'CMakeModule' in advance, it it EXISTS # $VERS = "0.0.3 2012-04-22"; # $VERS = "0.0.2 2012-01-29"; # $VERS = "0.0.1 2011-10-25"; my $inc_all_cmake = 1; # 26/04/2012 - If there exists a folder 'CMakeModules' load ALL from here... # double UGH - maybe should load, on demand, ALL modules in install [share\cmake-2.8\Modules]!!! my $load_installed_cmake = 0; # load ALL 200-300 ...cmake files from the install my $load_log = 0; my $in_file = ''; my $verbosity = 0; my $show_mess = 0; my $show_installs = 0; my $show_sets = 0; my $show_options = 0; my $show_lists = 0; my $show_binaries = 0; ### my $show_if_tags = 0; my $show_all = 0; my $warn_set_overwrites = 0; my $warn_macro_overwrites = 0; my $warn_not_expaned = 0; my $warn_unexpanded_fn = 0; my $warn_substitution_for = 0; # WARNING: Substitution for [ sub set_warn_all() { $warn_set_overwrites = 1; $warn_macro_overwrites = 1; $warn_not_expaned = 1; $warn_unexpanded_fn = 1; $warn_substitution_for = 1; } ### program variables # main action sub process_cmake_list($); # ref to file lines setup, and these are process sub process_in_file($$); # process a cmake script file my $total_file_lines = 0; my $total_files = 0; my @warnings = (); my $warnings_avoided = 0; my $cwd = cwd(); my $total_options = 0; my $total_lines = 0; my $total_bytes = 0; my ($cmake_moddir); # = $d."CMakeModules" my @cmake_actions = qw(CMAKE_MINIMUM_REQUIRED CMAKE_POLICY INCLUDE PROJECT SET FILE STRING MESSAGE FIND_LIBRARY LIST FIND_PACKAGE EXECUTE_PROCESS OPTION GET_FILENAME_COMPONENT CHECK_INCLUDE_FILE CHECK_CXX_SOURCE_COMPILES INCLUDE_DIRECTORIES ADD_DEFINITIONS CHECK_FUNCTION_EXISTS CONFIGURE_FILE ADD_SUBDIRECTORY INSTALL CONFIGURE_FILE ADD_CUSTOM_TARGET TARGET_LINK_LIBRARIES CHECK_INCLUDE_FILES CHECK_TYPE_SIZE ADD_LIBRARY SET_TARGET_PROPERTIES ADD_EXECUTABLE GET_TARGET_PROPERTY ADD_CUSTOM_COMMAND ADD_DEPENDENCIES FLTK_WRAP_UI GET_PROPERTY MARK_AS_ADVANCED GET_CMAKE_PROPERTY SET_PROPERTY TRY_COMPILE FIND_PATH FIND_PROGRAM FIND_PACKAGE_MESSAGE TRY_RUN FIND_PACKAGE_HANDLE_STANDARD_ARGS UNSET CMAKE_DETERMINE_COMPILER_ID EXEC_PROGRAM _FIND_ECLIPSE_VERSION PROCESSORCOUNT GETDEFAULTWINDOWSPREFIXBASE BREAK SET_COMPILE_FLAGS_VAR SET_LINK_FLAGS_VAR PRINTTESTCOMPILERSTATUS CMAKE_DETERMINE_COMPILER_ABI CRT_VERSION MATH CHECK_VERSION CMAKE_DETERMINE_COMPILER_ID_VENDOR ENABLE_TESTING SITE_NAME GET_VS_VERSION_STRING BUILD_COMMAND DEFINE_PROPERTY _BOOST_CHECK_SPELLING _BOOST_COMPILER_DUMPVERSION _BOOST_PREPEND_LIST_WITH_THREADAPI _BOOST_SWAP_WITH_REALPATH _BOOST_MARK_COMPONENTS_FOUND LOAD_CACHE FIND_FILE _GTEST_APPEND_DEBUGS _GTEST_FIND_LIBRARY _GTK2_FIND_INCLUDE_DIR _GTK2_FIND_LIBRARY _GTK2_GET_VERSION _PROTOBUF_FIND_LIBRARIES _QT4_QUERY_QMAKE ERROR_MESSAGE FIND_IMAGEMAGICK_API FIND_IMAGEMAGICK_EXE GET_DIRECTORY_PROPERTY INTERROGATE_MPI_COMPILER IS_FILE_EXECUTABLE LINK_DIRECTORIES LINK_LIBRARIES OSG_FIND_LIBRARY OSG_FIND_PATH OSG_MARK_AS_ADVANCED PKG_CHECK_MODULES SANITYCHECKSDKANDDEPLOYTARGET SEPARATE_ARGUMENTS SET_DIRECTORY_PROPERTIES TRY_REGULAR_COMPILER MACRO ENDMACRO FOREACH ENDFOREACH FUNCTION ENDFUNCTION RETURN ENABLE_LANGUAGE ); sub func_nul { }; my %cpack_actions = ( 'CPACK_SET_IF_NOT_SET' => \&func_nul, # act [(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}")] 'CPACK_CHECK_FILE_EXISTS' => \&func_nul, # act [("${CPACK_PACKAGE_DESCRIPTION_FILE}" "package description")] 'CPACK_OPTIONAL_APPEND' => \&func_nul, # act [(CPACK_GENERATOR CPACK_BINARY_BUNDLE Bundle)] 'CPACK_ENCODE_VARIABLES' => \&func_nul, # act [()] 'CPACK_PARSE_ARGUMENTS' => \&func_nul, # act [(CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME} "DISPLAY_NAME;DESCRIPTION;GROUP;DEPENDS;INSTALL_TYPES;ARCHIVE_FILE" "HIDDEN;REQUIRED;DISABLED;DOWNLOADED" ${ARGN} )] 'CPACK_APPEND_STRING_VARIABLE_SET_COMMAND' => \&func_nul, # act [( CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_DISPLAY_NAME CPACK_ADDCOMP_STR)] 'CPACK_APPEND_VARIABLE_SET_COMMAND' => \&func_nul, # act [( CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_GROUP CPACK_ADDCOMP_STR)] 'CPACK_APPEND_OPTION_SET_COMMAND' => \&func_nul # act [( CPACK_COMPONENT_${CPACK_ADDCOMP_UNAME}_HIDDEN CPACK_ADDCOMP_STR)] ); my %unlisted_tags = (); my %load_failed = (); my %macros_not_found = (); my %missing_list_action = (); my %unexpanded_macros = (); my %undefined_regex_match = (); my %uncased_file_action = (); my %uncased_string_action = (); my %not_found_in_set_or_list = (); my %action_is_uncased = (); my %undefined_strip_item = (); my %undefined_strip_item_macro = (); # DEBUG my $debug_on = 1; my $def_file = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Platform\Windows-cl.cmake'; #my $def_file = 'C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\GNUInstallDirs.cmake'; #my $def_file = 'C:\FGCVS\flightgear\source'; # $def_file = 'C:\Projects\freeglut'; # $def_file = 'C:\FG\30\flightgear'; my $dbg_01 = 0; my $dbg_02 = 0; # show prt("Action [$tag] $action\n") if ($dbg_02 || VERB9()); my $dbg_03 = 0; my $dbg_04 = 0; # MACRO and macro expansion my $dbg_05 = 0; # ADD_SUBDIRECTORY actions my $dbg_06 = 0; # prt("[v9] Collected FOREACH MACRO($item1) args $argc [$args], from $bgn to $end\n[$macro]\n") if (VERB9() || $dbg_06); my $dbg_07 = 0; # show save and restore stack my $dbg_08 = 0; # prt("[v9] Loading 'INCLUDE' [$ff]\n"); my $add_searched_debug = 0; 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 || $warnings_avoided) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); prt("With $warnings_avoided duplicates or disabled avoided\n") if ($warnings_avoided); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { ### prt( "\nNo warnings issued.\n\n" ); } } 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); } sub path_form($) { my $rp = shift; # = \$ff if ($os =~ /win/i) { ${$rp} = path_u2d(${$rp}); } else { ${$rp} = path_d2u(${$rp}); } } sub clean_action($) { my $act = shift; $act =~ s/^\(//; $act =~ s/\)$//; return $act; } sub extract_var($) { my $var = shift; # ${FLIGHTGEAR_VERSION} # ${versionFile} if ($var =~ /^\$\{(.+)\}$/) { return $1; } return $var; } my @tmpifstk = (); my $save_counter = 0; my @save_stack = (); sub save_ref_hash_stack($) { my $rh = shift; $save_stack[$save_counter][0] = ${$rh}{'PROJECT_SOURCE_DIR'}; $save_stack[$save_counter][1] = ${$rh}{"BASE_FILE"}; $save_stack[$save_counter][2] = ${$rh}{"BASE_LINES"}; $save_stack[$save_counter][3] = ${$rh}{'CURR_IF_STACK'}; $save_stack[$save_counter][4] = ${$rh}{'CURR_IN_IF'}; # zero IF counter $save_stack[$save_counter][5] = ${$rh}{"ACT_LCNT"}; $save_stack[$save_counter][6] = ${$rh}{'ACT_I'}; $save_stack[$save_counter][7] = ${$rh}{'CURR_LINE_SOURCE'}; # = "File [$inf]" or 'Macro $mnm'; @tmpifstk = (); ${$rh}{'CURR_IF_STACK'} = \@tmpifstk; my $svif = $save_stack[$save_counter][1]; prt("save_ref_hash_stack: [$svif]\n") if ($dbg_07); $save_counter++; } sub restore_ref_hash_stack($) { my $rh = shift; if ($save_counter) { $save_counter--; } else { pgm_exit(1,"restore_ref_hash_stack call out of turn!\n"); } ${$rh}{'PROJECT_SOURCE_DIR'} = $save_stack[$save_counter][0]; ${$rh}{"BASE_FILE"} = $save_stack[$save_counter][1]; ${$rh}{"BASE_LINES"} = $save_stack[$save_counter][2]; ${$rh}{'CURR_IF_STACK'} = $save_stack[$save_counter][3]; ${$rh}{'CURR_IN_IF'} = $save_stack[$save_counter][4]; ${$rh}{"ACT_LCNT"} = $save_stack[$save_counter][5]; ${$rh}{'ACT_I'} = $save_stack[$save_counter][6]; ${$rh}{'CURR_LINE_SOURCE'} = $save_stack[$save_counter][7]; # = "File [$inf]" or 'Macro $mnm'; my $svif = $save_stack[$save_counter][1]; prt("restore_ref_hash_stack: [$svif]\n") if ($dbg_07); } sub fix_directory($) { my $rd = shift; if (!(${$rd} =~ /(\\|\/)$/)) { ${$rd} .= $PATH_SEP; } } sub get_cmake_install_paths_ra() { my $envstg = $ENV{"PATH"}; my ($path,$up,@arr,$ver,$tmp,$cnt); my @paths = (); #prt("ENV(PATH) = $envstg\n"); @arr = split(";",$envstg); $cnt = scalar @arr; #prt("Got $cnt paths to test...\n"); foreach $path (@arr) { #prt("Testing [$path]\n"); next if (length($path) == 0); if ($path =~ /CMake/i) { $path =~ s/(\\|\/)bin$//i; $ver = ''; if (-d $path) { #$up = path_d2u($path); $up = path_u2d($path); prt("Adding path [$up]\n"); @arr = split(/(\/|\\)+/,$up); foreach $tmp (@arr) { if ($tmp =~ /cmake/i) { $ver = $tmp; last; } } push(@paths,[$up,$ver]); } else { prtw("WARNING: Not a valid DIRECTORY! [$path]\n"); } } else { # prt("Not 'CMake' related!\n"); } } return \@paths; } sub scan_cmake_path($$); sub scan_cmake_path($$) { my ($path,$rh) = @_; # my @installed_files = (); # ${$rh}{'CMAKE_INSTALLED_FILES'} = \@installed_files; my $rif = ${$rh}{'CMAKE_INSTALLED_FILES'}; my @dirs = (); if (opendir(DIR,$path)) { my @files = readdir(DIR); closedir(DIR); my ($file,$ff); fix_directory(\$path); foreach $file (@files) { next if (($file eq '.')||($file eq '..')); $ff = $path.$file; if (-l $ff) { # ignore links } elsif (-d $ff) { push(@dirs,$ff); } elsif (-f $ff) { if ($file =~ /\.cmake$/i) { #prt("adding file [$ff]\n"); push(@{$rif},$ff); } } else { prtw("WARNING: Unable to find file [$ff]!\n"); } } foreach $path (@dirs) { scan_cmake_path($path,$rh); } } else { prtw("WARNING: Unable to open directory [$path]!\n"); } } sub scan_cmake_install_paths($) { my $rh = shift; my $rval = 0; my $rp = get_cmake_install_paths_ra(); my $cnt = scalar @{$rp}; if ($cnt) { my ($i,$path,$ver); for ($i = 0; $i < $cnt; $i++) { $path = ${$rp}[$i][0]; scan_cmake_path($path,$rh); } } else { prtw("WARNING: Found NO Cmake install paths!\n"); $rval = 1; } return $rval; } my @list_operations = qw( LENGTH GET APPEND FIND INSERT REMOVE_ITEM REMOVE_AT REMOVE_DUPLICATES REVERSE SORT ); sub is_in_list_operations($) { my $act = shift; my ($itm); foreach $itm (@list_operations) { return 1 if ($act eq $itm); } return 0; } my @add_library_adjectives = qw ( SHARED STATIC MODULE UNKNOWN IMPORTED GLOBAL EXCLUDE_FROM_ALL ); sub is_add_library_adjective($) { my $act = shift; my ($itm); foreach $itm (@add_library_adjectives) { return 1 if ($act eq $itm); } return 0; } my @add_executable_adjectives = qw ( WIN32 MACOSX_BUNDLE EXCLUDE_FROM_ALL IMPORTED GLOBAL ); sub is_add_executable_adjective($) { my $act = shift; my ($itm); foreach $itm (@add_executable_adjectives) { return 1 if ($act eq $itm); } return 0; } sub string_to_directives_ra($) { my ($txt) = shift; my $len = length($txt); my ($i,$ch,$inquot,$pc,$pc2); $inquot = 0; my @braces = (); my @lines = (); # accumulate lines my $ntxt = ''; # accumulate a line $ch = ''; $pc = ''; for ($i = 0; $i < $len; $i++) { $pc2 = $pc; $pc = $ch; $ch = substr($txt,$i,1); if ($inquot) { if ($ch =~ /\s/) { $ntxt .= ' ' if ($ntxt =~ /\S$/g); } else { $ntxt .= $ch; $inquot = 0 if ( ($ch eq '"') && ( ($pc ne "\\") || ( ($pc eq "\\")&&($pc2 eq "\\") ) ) ); } } elsif ($ch eq '"') { $ntxt .= $ch; $inquot = 1; # if ($pc ne "\\"); } elsif ($ch eq '(') { $ntxt .= $ch; push(@braces,$ch); } elsif ($ch eq ')') { $ntxt .= $ch; if (@braces) { pop @braces; } if (!@braces) { push(@lines,$ntxt) if (length($ntxt)); $ntxt = ""; # start again } } elsif ($ch eq "\n") { # no add of this, but a space if length and not a trailing space $ntxt .= ' ' if (length($ntxt) && ($ntxt =~ /\S$/g)); } elsif ($ch eq '#') { # eat comments for (; $i < $len; $i++) { $ch = substr($txt,$i,1); last if ($ch eq "\n"); } } else { if ($ch =~ /\s/) { $ntxt .= ' ' if ($ntxt =~ /\S$/g); } else { $ntxt .= $ch; } } } $ntxt =~ s/\s$//g; push(@lines,$ntxt) if (length($ntxt)); return \@lines; } sub not_same_ref_array($$) { my ($ra1,$ra2) = @_; # $pia,\@list)) { my $ac1 = scalar @{$ra1}; my $ac2 = scalar @{$ra2}; return 1 if ($ac1 != $ac2); my ($i); my @arr1 = sort @{$ra1}; my @arr2 = sort @{$ra2}; for ($i = 0; $i < $ac1; $i++) { return 1 if ($arr1[$i] ne $arr2[$i]); } return 0; } sub process_action($) { my $rh = shift; my ($tag,$action,$lnn,$tline,$val); my ($item1,$item2,$item3); my $bfile = ${$rh}{"BASE_FILE"}; $tag = ${$rh}{"ACT_TAG"}; $action = ${$rh}{"ACT_ACT"}; $lnn = ${$rh}{"ACT_LNN"}; $tline = ${$rh}{"ACT_LINE"}; my $rdefs = ${$rh}{'CMAKE_DEFINES'}; # = \%defines; my $rlines = ${$rh}{"BASE_LINES"}; my ($msg,$act,@arr,$act2,$file,$var,$act3,$ff); my ($nm,$dr); my ($i,$i2,$cnt,$tmp,$ok,$ra,$key); prt("[v9] Action [$tag] $action\n") if ($dbg_02 || VERB9()); $act = clean_action($action); @arr = space_split($act); $cnt = scalar @arr; if ($tag eq "CMAKE_MINIMUM_REQUIRED") { } elsif ($tag eq 'CMAKE_POLICY') { } elsif ($tag eq 'ADD_CUSTOM_TARGET') { } elsif ($tag eq 'ADD_CUSTOM_COMMAND') { } elsif ($tag eq 'ADD_DEPENDENCIES') { } elsif ($tag eq 'ADD_DEFINITIONS') { } elsif ($tag eq 'ADD_SUBDIRECTORY') { # This should be processed for a CMakeLists.txt file here # my @subdirs = (); # $hash{'CMAKE_SUBDIRS'} = \@subdirs; $msg = ''; my $rsubs = ${$rh}{'CMAKE_SUBDIRS'}; my ($bname,$bdir) = fileparse($bfile); for ($i = 0; $i < $cnt; $i++) { $item1 = $arr[$i]; $tmp = $bdir.$item1.$PATH_SEP."CMakeLists.txt"; if (-f $tmp) { push(@{$rsubs},[$item1,$tmp]); $msg = ", file [$tmp]"; } else { $msg = "WARNING: Can NOT locate [$tmp]! base [$bfile]"; prtw("$msg\n"); } } prt("[v9] ADD_SUBDIRECTORY $i $action $msg\n") if ($dbg_05 || VERB9()); } elsif ($tag eq 'ADD_LIBRARY') { # add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED [GLOBAL]) # add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN) # my %libs_sources = (); # $hash{'CMAKE_LIBS'} = \%libs_sources; my $rlibs = ${$rh}{'CMAKE_LIBS'}; $item1 = $arr[0]; # get LIBRARY name if ($cnt >= 2) { my @lsrcs = (); for ($i = 1; $i < $cnt; $i++) { $item2 = $arr[$i]; # get adjective or first source next if (is_add_library_adjective($item2)); push(@lsrcs,$item2); } if (defined ${$rlibs}{$item1}) { prtw("WARNING: add_library entry IS DUPLICATED\n"); } else { ${$rlibs}{$item1} = \@lsrcs; } } else { prtw("WARNING: BAD add_library entry [$tag] $action\n"); } } elsif ($tag eq 'ADD_EXECUTABLE') { # add_executable(<name> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN) # add_executable(<name> IMPORTED [GLOBAL]) # my %exes_sources = (); # $hash{'CMAKE_EXES'} = \%exes_sources; my $rexes = ${$rh}{'CMAKE_EXES'}; $item1 = $arr[0]; # get LIBRARY name if ($cnt >= 2) { my @esrcs = (); for ($i = 1; $i < $cnt; $i++) { $item2 = $arr[$i]; # get adjective or first source next if (is_add_executable_adjective($item2)); push(@esrcs,$item2); } if (defined ${$rexes}{$item1}) { prtw("WARNING: add_executable entry IS DUPLICATED\n"); } else { ${$rexes}{$item1} = \@esrcs; } } else { prtw("WARNING: BAD add_executable entry [$tag] $action\n"); } } elsif ($tag eq "INCLUDE") { # This maybe a FILE to be loaded like include(FlightGearComponent) = \CMakeModules\FlightGearComponent.cmake file # or it can be a 'standard' CMakeMoudles file from the installation # See Directory of C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Platform # ===================================================================================================================== $item1 = $arr[0]; # get INCLUDE base name $item2 = ${$rh}{'PRIMARY_CMAKE_DIR'}; $ff = $item2; $ff .= "CMakeModules".$PATH_SEP; $ff .= "$item1.cmake"; $ok = 0; my @tries = (); if (-f $ff) { $ok = 1; } else { push(@tries,$ff); my $envstg = $ENV{"PATH"}; my @parr = split(/;+/,$envstg); foreach $tmp (@parr) { next if (!($tmp =~ /cmake/i)); $tmp =~ s/(\\|\/)bin/\\/; $ff = $tmp."share\\cmake-2.8\\Modules\\$item1.cmake"; if (-f $ff) { $ok = 1; last; } push(@tries,$ff); $ff = $tmp."Modules\\$item1.cmake"; if (-f $ff) { $ok = 1; last; } push(@tries,$ff); $ff = $tmp."share\\cmake-2.8\\Modules\\Platform\\$item1.cmake"; if (-f $ff) { $ok = 1; last; } push(@tries,$ff); } } if ($ok) { my $svverb = $verbosity; $verbosity = 9 if ($dbg_08); prt("[v9] Loading 'INCLUDE' [$ff]\n") if (VERB9()); # SAVE CERTAIN VARIABLES FROM CHANGE save_ref_hash_stack($rh); process_in_file($ff,$rh); # RESTORE CERTAIN VARIABLES BACK TO FORMER restore_ref_hash_stack($rh); # pgm_exit(1,"TEMP EXIT"); $verbosity = $svverb; } elsif (!defined $load_failed{$item1}) { $load_failed{$item1} = 1; if ($item1 =~ /\$\{(\w+)\}/) { $val = $1; if (!defined $unexpanded_macros{$val}) { $unexpanded_macros{$val} = 1; if ($warn_not_expaned) { prtw("WARNING: Unable to load INCLUDE [$item1] due to MACRO [$val] NOT expanded\n"); } else { $warnings_avoided++; } } } else { prtw("WARNING: Unable to locate INCLUDE [$item1] TRIED \n".join("\n",@tries)."!\n"); } } } elsif ($tag eq 'PROJECT') { # CMAKE_PROJECT_NAME $val = strip_quotes($arr[0]); ${$rh}{'PROJ_NAME'} = $val; prt("$lnn: $tag = $val\n"); } elsif ($tag eq 'SET') { # should be a VARIABLE item1 [item2 [item3...]]] my $rsmh = ${$rh}{'CMAKE_SETMACROS'}; # my @arr = sort keys(%{$rsmh}); $val = $arr[0]; # get the variable my @list = (); for ($i = 1; $i < $cnt; $i++) { push(@list,$arr[$i]); } # $set_macros{$val} = \@list; if (defined ${$rsmh}{$val}) { if ($warn_set_overwrites) { if ((${$rh}{'CURR_IN_IF'} == 0) && !($val =~ /^CMAKE_/i)) { my $pia = ${$rsmh}{$val}; if (not_same_ref_array($pia,\@list)) { $msg = "WARNING: SET variable [$val] being overwritten with NEW list! No IF \nIn file [$bfile]($lnn)]\n"; $msg .= "prev [".join(";",sort @{$pia})."]\n"; $msg .= "curr [".join(";",sort @list)."]\n"; prtw($msg); } } else { $warnings_avoided++; } } else { $warnings_avoided++; } } ${$rsmh}{$val} = \@list; } elsif ($tag eq 'FILE') { # file(READ version versionFile) $act2 = $arr[0]; if ($act2 eq 'READ') { $file = strip_quotes($arr[1]); $val = strip_quotes($arr[2]); ${$rh}{"FILE_VAR"} = $val; if (! -f $file) { ($nm,$dr) = fileparse($bfile); $file = $dr.$file } if (-f $file) { if (open FIL,"<$file") { my @lines = ; close FIL; $cnt = scalar @lines; for ($i = 0; $i < $cnt; $i++) { $tmp = trim_all($lines[$i]); $lines[$i] = $tmp; } ${$rh}{$val} = join(" ",@lines); prt("Loaded FILE(READ [".${$rh}{$val}."]) into $val\n") if (VERB9()); } else { prtw("WARNING: Unable to open FILE [$file] $tline [$bfile]$lnn\n"); } } else { if ($file =~ /\$\{(\w+)\}/) { $val = $1; if ($warn_unexpanded_fn) { prtw("WARNING: Unable to find FILE [$file] due unexpanded [$val] [$bfile]$lnn\n"); } else { $warnings_avoided++; } } else { prtw("WARNING: Unable to find FILE [$file] $tline [$bfile]$lnn\n"); } } } elsif ($act2 eq 'WRITE') { # ***TBD*** TODO } elsif ($act2 eq 'APPEND') { # ***TBD*** TODO } elsif ($act2 eq 'GLOB_RECURSE') { # ***TBD*** TODO # file((GLOB_RECURSE _JAVA_GLOBBED_FILES "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/*.class") [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\UseJavaClassFilelist.cmake]34 } elsif ($act2 eq 'RELATIVE_PATH') { # ***TBD*** TODO # file((RELATIVE_PATH _JAVA_CLASS_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH} ${_JAVA_GLOBBED_FILES}) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\UseJavaClassFilelist.cmake]1 } elsif ($act2 eq 'MAKE_DIRECTORY') { # ***TBD*** TODO # FILE((MAKE_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY}/debian) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackDeb.cmake]182 } elsif ($act2 eq 'REMOVE_RECURSE') { # ***TBD*** TODO # FILE((REMOVE_RECURSE "${CPACK_TEMPORARY_DIRECTORY}/debian") [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackDeb.cmake]211 } elsif ($act2 eq 'REMOVE') { # ***TBD*** TODO # FILE((REMOVE ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake ) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeTestCCompiler.cmake]50 } elsif ($act2 eq 'GLOB') { # ***TBD*** TODO # FILE((GLOB _CMAKE_OSX_SDKS "${OSX_DEVELOPER_ROOT}/SDKs/*") [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Platform\Darwin.cmake]63 } elsif ($act2 eq 'STRINGS') { # ***TBD*** TODO # file((STRINGS "${CMAKE_CURRENT_LIST_FILE}" linesLIMIT_COUNT ${_ep_documentation_line_count}REGEX "^# ( \\[[A-Z0-9_]+ [^]]*\\] +#.*$|[A-Za-z0-9_]+\\()") [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\ExternalProject.cmake]163 } elsif ($act2 eq 'TO_CMAKE_PATH') { # ***TBD*** TODO # file((TO_CMAKE_PATH ${BOOST_ROOT} BOOST_ROOT) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake]602 } elsif ($act2 eq 'COPY') { # ***TBD*** TODO # file((COPY ${FortranCInterface_SOURCE_DIR}/DESTINATION ${CMAKE_BINARY_DIR}/CMakeFiles/FortranCInterfaceMinGW) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FortranCInterface.cmake]123 } else { if (!defined $uncased_file_action{$act2}) { $uncased_file_action{$act2} = 1; prtw("WARNING: Uncased FILE action [$act2] $tline [$bfile]$lnn\n"); } else { $warnings_avoided++; } } } elsif ($tag eq 'STRING') { # 0 1 2 3 4 # act2 act3 $item1 $item2 $item3 # string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" CPACK_PACKAGE_VERSION ${FLIGHTGEAR_VERSION} ) $act2 = $arr[0]; if ($act2 eq 'STRIP') { # string(STRIP ${versionFile} FLIGHTGEAR_VERSION) $item1 = extract_var($arr[1]); $item2 = $arr[2]; if (defined ${$rh}{$item1}) { ${$rh}{$item2} = trim_all(${$rh}{$item1}); } else { if ($item1 =~ /^\"*\$\{(\w+)\}\"*$/) { $tmp = $1; if (!defined $undefined_strip_item_macro{$tmp}) { $undefined_strip_item_macro{$tmp} = 1; prtw("WARNING: Undefined STRIP item macro [$tmp] [$item1] $tline [$bfile]$lnn\n"); } else { $warnings_avoided++; } } elsif (!defined $undefined_strip_item{$item1}) { $undefined_strip_item{$item1} = 1; prtw("WARNING: Undefined STRIP item [$item1] $tline [$bfile]$lnn\n"); } else { $warnings_avoided++; } } } elsif ($act2 eq 'REGEX') { $act3 = $arr[1]; if ($act3 eq 'MATCH') { $item1 = strip_quotes($arr[2]); $item1 =~ s/\\\\/\\/g; $item2 = $arr[3]; $item3 = extract_var($arr[4]); if (defined ${$rh}{$item3}) { $val = ${$rh}{$item3}; if ($val =~ m/($item1)/) { ${$rdefs}{$item2} = $1; for ($i = 1; ; $i++) { $i2 = $i + 1; if (eval "defined \$$i2") { $var = "CMAKE_MATCH_$i"; ${$rdefs}{$var} = eval "\$$i2"; prt("\$$i2 = ".${$rdefs}{$var}." in $var\n"); } else { last; } } prt("Got $item2 = ".${$rdefs}{$item2}."\n"); } else { prtw("REGEX MATCH FAILED! on if ($val =~ /($item1)/)! [$bfile]$lnn\n"); } } else { # WARNING: Undefined REGEX MATCH item [IN] string((REGEX MATCH "%[A-Za-z\(\)]*" F_PREFIX IN) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackRPM.cmake]2 # WARNING: Undefined REGEX MATCH item [LISTS] string((REGEX MATCH "%[A-Za-z\(\)]*" F_PREFIX LISTS) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackRPM.cmake]2 # WARNING: Undefined REGEX MATCH item [CPACK_RPM_USER_FILELIST_INTERNAL] string((REGEX MATCH "%[A-Za-z\(\)]*" F_PREFIX CPACK_RPM_USER_FILELIST_INTERNAL) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackRPM.cmake]2 if (!defined $undefined_regex_match{$item3}) { $undefined_regex_match{$item3} = 1; prtw("WARNING: Undefined REGEX MATCH item [$item3] $tline [$bfile]$lnn\n"); } else { $warnings_avoided++; } } } elsif ($act3 eq 'REPLACE') { # ***TBD*** TODO } elsif ($act3 eq 'MATCHALL') { # ***TBD*** TODO # WARNING: Uncase STRING REGEX [MATCHALL] action - STRING((REGEX MATCHALL "-I[^;]+"wxWidgets_INCLUDE_DIRS "${wxWidgets_CXX_FLAGS}") [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindwxWidgets.cmake]752 } else { prtw("WARNING: Uncase STRING REGEX [$act3] action - $tline [$bfile]$lnn\n"); } } elsif ($act2 eq 'TOUPPER') { # ***TBD*** TODO } elsif ($act2 eq 'REPLACE') { # ***TBD*** TODO } elsif ($act2 eq 'LENGTH') { # ***TBD*** TODO # STRING((LENGTH AUTOREQ _PACKAGE_HEADER_STRLENGTH) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackRPM.cmake]24 } elsif ($act2 eq 'SUBSTRING') { # ***TBD*** TODO # STRING((SUBSTRING AUTOREQ 1 ${_PACKAGE_HEADER_STRLENGTH} _PACKAGE_HEADER_TAIL) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackRPM.cmake]26 } elsif ($act2 eq 'TOLOWER') { # ***TBD*** TODO # STRING((TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackDeb.cmake]241 } elsif ($act2 eq 'COMPARE') { # ***TBD*** TODO # STRING((COMPARE NOTEQUAL "${QT_QMAKE_EXECUTABLE_LAST}" "${QT_QMAKE_EXECUTABLE}" QT_QMAKE_CHANGED) [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindQt4.cmake]488 } else { if (!defined $uncased_string_action{$act2}) { $uncased_string_action{$act2} = 1; prtw("WARNING: Uncased STRING action [$act2] $tline [$bfile]$lnn\n"); } else { $warnings_avoided++; } } } elsif ($tag eq 'MESSAGE') { prt("$lnn: $tag $arr[0] [".strip_quotes($arr[1])."]\n") if ($show_mess || $dbg_03); } elsif ($tag eq 'FIND_LIBRARY') { } elsif ($tag eq 'LIST') { # $hash{'CMAKE_LISTS'} = \%list_items; my $rli = ${$rh}{'CMAKE_LISTS'}; $item1 = $arr[0]; $ok = is_in_list_operations($item1); if ($ok && ($cnt >= 2)) { $item2 = $arr[1]; my @larr = (); my $lcnt = 0; for ($i = 2; $i < $cnt; $i++) { push(@larr, $arr[$i]); $lcnt++; } if (defined ${$rli}{$item2}) { # already have this LIST prt("LIST [$item1] op [$item2] already EXISTS, $lcnt new items\n") if (VERB9()); } else { # is a NEW list ${$rli}{$item2} = []; prt("LIST [$item1] op [$item2] is NEW\, $lcnt new items\n") if (VERB9()); } $ra = ${$rli}{$item2}; if ($item1 eq 'APPEND') { push(@{$ra},@larr); } elsif ($item1 eq 'LENGTH') { # ***TBD*** TODO } elsif ($item1 eq 'FIND') { # ***TBD*** TODO } elsif ($item1 eq 'GET') { # ***TBD*** TODO } elsif ($item1 eq 'REMOVE_ITEM') { # WARNING: LIST [REMOVE_ITEM] op [depends_CUDA_NVCC_FLAGS] operation NOT handled yet TODO! # ***TBD*** TODO } elsif ($item1 eq 'REMOVE_DUPLICATES') { # ***TBD*** TODO # WARNING: LIST [REMOVE_DUPLICATES] op [dependency_list] operation NOT handled yet TODO! [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCUDA\make2cmake.cmake]86 } elsif ($item1 eq 'SORT') { # ***TBD*** TODO # WARNING: LIST [SORT] op [dependency_list] operation NOT handled yet TODO! [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCUDA\make2cmake.cmake]87 } elsif ($item1 eq 'REMOVE_AT') { # ***TBD*** TODO # WARNING: LIST [REMOVE_AT] op [MPI_EXTRA_LIBRARY_WORK] operation NOT handled yet TODO! [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindMPI.cmake]604 } else { # WARNING: LIST [GET] op [pieces] operation NOT handled yet TODO! if (!defined $missing_list_action{$item1}) { $missing_list_action{$item1} = 1; prtw("WARNING: LIST [$item1] op [$item2] operation NOT handled yet TODO! [$bfile]$lnn\n"); } else { $warnings_avoided++; } } } else { if ($ok) { prtw("WARNING: LIST operation [$item1] has insufficient elements! [$bfile]$lnn\n"); } else { prtw("WARNING: LIST operation [$item1] UNKNOWN [$bfile]$lnn\n"); } } } elsif ($tag eq 'FIND_PACKAGE') { } elsif ($tag eq 'EXECUTE_PROCESS') { } elsif ($tag eq 'OPTION') { # option(SP_FDMS "Set to ON to build FlightGear with special-purpose FDMs" OFF) $item1 = $arr[0]; $item2 = $arr[1]; $item3 = $arr[2]; ${$rdefs}{$item1} = (($item3 eq 'OFF') ? 0 : ($item3 eq 'ON') ? 1 : 0); ${$rdefs}{"MESSAGE-$item1"} = strip_quotes($item2); # see process_cmake_OPTION_lines($rh) for setting 'CMAKE_OPTIONS' array } elsif ($tag eq 'GET_FILENAME_COMPONENT') { } elsif ($tag eq 'CHECK_INCLUDE_FILE') { } elsif ($tag eq 'CHECK_CXX_SOURCE_COMPILES') { } elsif ($tag eq 'INCLUDE_DIRECTORIES') { } elsif ($tag eq 'CHECK_FUNCTION_EXISTS') { } elsif ($tag eq 'CONFIGURE_FILE') { } elsif ($tag eq 'INSTALL') { # my @install_actions = (); # ${$rh}{'CMAKE_INSTALLS'} = \@install_actions; my $ria = ${$rh}{'CMAKE_INSTALLS'}; # push(@install_actions,[$lnn,$act]); push(@{$ria},[$lnn,$act]); } elsif ($tag eq 'CONFIGURE_FILE') { } elsif ($tag eq 'CHECK_INCLUDE_FILES') { } elsif ($tag eq 'CHECK_TYPE_SIZE') { } elsif ($tag eq 'GET_TARGET_PROPERTY') { } elsif ($tag eq 'SET_TARGET_PROPERTIES') { } elsif ($tag eq 'TARGET_LINK_LIBRARIES') { } elsif ($tag eq 'MACRO') { # must collect until ENDMACRO $item1 = $arr[0]; # get MACRO name my $lncnt = ${$rh}{"ACT_LCNT"}; $lnn = ${$rh}{"ACT_LNN"}; my $macro = ''; my $args = ''; my $argc = 0; for ($i = 1; $i < $cnt; $i++) { $args .= ' ' if (length($args)); $args .= $arr[$i]; $argc++; } my $bgn = $lnn; my $line = ''; for (;$lnn < $lncnt ; $lnn++) { $line = ${$rlines}[$lnn]; chomp $line; last if ($line =~ /^\s*ENDMACRO/i); $macro .= "$line\n"; } $macro =~ s/\s$//g; prt("[v9] MACRO name $item1, args $argc [$args]\n") if ($dbg_04 || VERB9()); my $rma = ${$rh}{'CMAKE_MACROS'}; # $len = length($macro); if (defined ${$rma}{$item1}) { if ( ${$rh}{'CURR_IN_IF'} == 0 ) { # NOT in any IF if ($warn_macro_overwrites) { prtw("WARNING: Macro [$item1] ALREADY EXIST! Being overwritten!\n"); } else { $warnings_avoided++; } } } #my $rdia = string_to_directives_ra($macro); #$macro = join("\n",@{$rdia}); # 0 1 ${$rma}{$item1} = [$args,$macro]; ${$rh}{'ACT_I'} = $lnn; # move forward my $end = $lnn + 1; for ($lnn = 1; $lnn < $cnt; $lnn++) { $item1 .= ' '; $item1 .= $arr[$lnn]; } prt("[v9] Collected MACRO($item1) from $bgn to $end, stored in 'CMAKE_MACROS'\n[$macro]\n") if (VERB9()); } elsif ($tag eq 'FUNCTION') { # must eat until ENDFUNCTION # FindPackageMessage # FIND_PACKAGE_MESSAGE( "message for user" "find result details") # my %functions = (); # ${$rh}{'CMAKE_FUNCTIONS'} = \%functions; $item1 = $arr[0]; # get FUNCTION name my $lncnt = ${$rh}{"ACT_LCNT"}; $lnn = ${$rh}{"ACT_LNN"}; my $line = ''; my $function = ''; for (;$lnn < $lncnt ; $lnn++) { $line = ${$rlines}[$lnn]; chomp $line; $line = trim_all($line); last if ($line =~ /^ENDFUNCTION/i); next if (length($line) == 0); $function .= "$line\n"; } my $rfh = ${$rh}{'CMAKE_FUNCTIONS'}; ${$rfh}{$item1} = $function; # move the file lines FORWARD # ============================================ ${$rh}{'ACT_I'} = $lnn; # move forward # ============================================ } elsif ($tag eq 'FOREACH') { # must eat until ENDFOREACH # BUT WATCH OUT FOR NESTED FOREACH LIKE # foreach (lang C CXX Fortran) # foreach (id GNU Intel PGI XL) # if (NOT CMAKE_${lang}_COMPILER_ID OR "${CMAKE_${lang}_COMPILER_ID}" STREQUAL "${id}") # list(APPEND _MPI_${lang}_COMPILER_NAMES ${_MPI_${id}_${lang}_COMPILER_NAMES}) # endif() # unset(_MPI_${id}_${lang}_COMPILER_NAMES) # clean up the namespace here # endforeach() # endforeach() $item1 = $arr[0]; # get MACRO name my $lncnt = ${$rh}{"ACT_LCNT"}; $lnn = ${$rh}{"ACT_LNN"}; my $macro = ''; my $args = ''; my $argc = 0; for ($i = 1; $i < $cnt; $i++) { $tmp = $arr[$i]; # extract the ARGUMENT item if ($tmp =~ /^\${(\w+)\}$/) { # got a macro to EXPAND # - check in 'SET' lists $val = $1; $ok = 0; my $rsmh = ${$rh}{'CMAKE_SETMACROS'}; my @slarr = keys(%{$rsmh}); foreach $key (@slarr) { if ($key eq $val) { $tmp = ${$rsmh}{$key}; $ok = 1; last; } } if (!$ok) { # - check in 'LIST' lists my $rli = ${$rh}{'CMAKE_LISTS'}; # $ok = is_in_list_operations($item1); @slarr = keys(%{$rli}); foreach $key (@slarr) { if ($key eq $val) { $tmp = ${$rli}{$key}; $ok = 1; last; } } } if (!$ok) { if (!defined $not_found_in_set_or_list{$val}) { $not_found_in_set_or_list{$val} = 1; if ($warn_substitution_for) { prtw("WARNING: Substitution for [$tmp] [$val] NOT FOUND IN 'SET' or 'LIST'! act [$action] [$bfile]$lnn\n"); } else { $warnings_avoided++; } } else { $warnings_avoided++; } } } $args .= ' ' if (length($args)); $args .= $tmp; $argc++; } my $bgn = $lnn; my $line = ''; for (;$lnn < $lncnt ; $lnn++) { $line = ${$rlines}[$lnn]; chomp $line; $line = trim_all($line); last if ($line =~ /^ENDFOREACH/i); next if (length($line) == 0); $macro .= "$line\n"; } $macro =~ s/\s$//g; my $end = $lnn + 1; prt("[v9] Collected FOREACH MACRO($item1) args $argc [$args], from $bgn to $end\n[$macro]\n") if (VERB9() || $dbg_06); my $rdia = string_to_directives_ra($macro); prt("[v9] Trimmed actions [".join("\n",@{$rdia})."]\n") if (VERB9() || $dbg_06); # [v9] Collected FOREACH MACRO(mylibfolder) args 24 [Airports Aircraft ATC ATCDCL Radio ... ] from 31 to 34 # Trimmed actions [add_subdirectory(${mylibfolder})] # in sub process_cmake_list($) # SAVE CERTAIN VARIABLES FROM CHANGE save_ref_hash_stack($rh); $msg = ''; for ($i = 1; $i < $cnt; $i++) { $args = $arr[$i]; $macro = join("\n",@{$rdia}); my $orgtxt = $macro; $macro =~ s/\$\{$item1\}/$args/g; prt("[v9] After substitution [$macro]\n") if (VERB9() || $dbg_06); if (($orgtxt eq $macro)&&(length($msg)==0)) { $msg = "WARNING: Substitution of [$item1] to [$args] FAILED! "; $msg .= "File [$bfile]($bgn)"; } my @lines = split("\n",$macro); # get back into an array ${$rh}{"BASE_LINES"} = \@lines; ${$rh}{'CURR_LINE_SOURCE'} = "Macro $item1 subs"; process_cmake_list($rh); } prt("$msg\n") if (length($msg)); prt("[v9] Completed $argc MACRO($item1) substitutions...\n") if (VERB9() || $dbg_06); # RESTORE CERTAIN VARIABLES BACK TO FORMER restore_ref_hash_stack($rh); # move the file lines FORWARD # ============================================ ${$rh}{'ACT_I'} = $lnn; # move forward # ============================================ } elsif ($tag eq 'FLTK_WRAP_UI') { } elsif ($tag eq 'GET_PROPERTY') { } elsif ($tag eq 'MARK_AS_ADVANCED') { } elsif ($tag eq 'GET_CMAKE_PROPERTY') { } elsif ($tag eq 'SET_PROPERTY') { # act [(GLOBAL APPEND PROPERTY FG_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${sources}")] in [C:\FGCVS\flightgear\source\src\Airports\CMakeLists.txt] } elsif ($tag eq 'TRY_COMPILE') { # act [(${VAR} ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} "${CHECK_CXX_SOURCE_COMPILES_ADD_LIBRARIES}" "${CHECK_CXX_SOURCE_COMPILES_ADD_INCLUDES}" OUTPUT_VARIABLE OUTPUT)] in [C:\FGCVS\flightgear\source\src\Airports\CMakeLists.txt]39 } elsif ($tag eq 'FIND_PATH') { # act [(ALUT_INCLUDE_DIR alut.h HINTS $ENV{ALUTDIR} PATH_SUFFIXES include/AL include/ALUT include PATHS ~/Library/Frameworks /Library/Frameworks /usr/local /usr /opt )] } elsif ($tag eq 'FIND_PROGRAM') { # act [(GIT_EXECUTABLE NAMES ${git_names} DOC "git command line client" )] } elsif ($tag eq 'RETURN') { # ***TBD** TODO } elsif ($tag eq 'FIND_PACKAGE_MESSAGE') { # ***TBD** TODO # act [(X11 "Found X11: ${X11_X11_LIB}" "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindX11.cmake]408 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindX11.cmake] } elsif ($tag eq 'TRY_RUN') { # ***TBD** TODO # act [(THREADS_PTHREAD_ARG THREADS_HAVE_PTHREAD_ARG ${CMAKE_BINARY_DIR} ${CMAKE_ROOT}/Modules/CheckForPthreads.c CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread COMPILE_OUTPUT_VARIABLE OUTPUT)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindThreads.cmake]84 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindThreads.cmake] } elsif ($tag eq 'FIND_PACKAGE_HANDLE_STANDARD_ARGS') { # ***TBD** TODO # act [(Threads DEFAULT_MSG Threads_FOUND)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindThreads.cmake]157 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindThreads.cmake] } elsif ($tag eq 'UNSET') { # ***TBD** TODO # act [(CMAKE_C_ABI_FILES)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeCInformation.cmake]75 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeCInformation.cmake] } elsif ($tag eq 'CMAKE_DETERMINE_COMPILER_ID') { # ***TBD** TODO # act [(C CFLAGS CMakeCCompilerId.c)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeDetermineCCompiler.cmake]130 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeDetermineCCompiler.cmake] } elsif ($tag eq 'EXEC_PROGRAM') { # ***TBD** TODO # act [(${CMAKE_Fortran_COMPILER} ARGS ${CMAKE_Fortran_COMPILER_ID_FLAGS_LIST} -E "\"${CMAKE_ROOT}/Modules/CMakeTestGNU.c\"" OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT RETURN_VALUE CMAKE_COMPILER_RETURN)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeDetermineFortranCompiler.cmake]183 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeDetermineFortranCompiler.cmake] } elsif ($tag eq '_FIND_ECLIPSE_VERSION') { # ***TBD** TODO # act [()] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindEclipseCDT4.cmake]55 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindEclipseCDT4.cmake] } elsif ($tag eq 'PROCESSORCOUNT') { # ***TBD** TODO # act [(_CMAKE_ECLIPSE_PROCESSOR_COUNT)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindEclipseCDT4.cmake]61 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindEclipseCDT4.cmake] } elsif ($tag eq 'GETDEFAULTWINDOWSPREFIXBASE') { # ***TBD** TODO # act [(CMAKE_GENERIC_PROGRAM_FILES)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeGenericSystem.cmake]162 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeGenericSystem.cmake] } elsif ($tag eq 'BREAK') { # ***TBD** TODO # act [()] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindPackageMode.cmake]3 src [Macro file subs] } elsif ($tag eq 'SET_COMPILE_FLAGS_VAR') { # ***TBD** TODO # act [(${NAME})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindPackageMode.cmake]178 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindPackageMode.cmake] } elsif ($tag eq 'SET_LINK_FLAGS_VAR') { # ***TBD** TODO # act [(${NAME})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindPackageMode.cmake]180 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeFindPackageMode.cmake] } elsif ($tag eq 'PRINTTESTCOMPILERSTATUS') { # ***TBD** TODO # act [("C" "")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeTestCCompiler.cmake]23 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeTestCCompiler.cmake] } elsif ($tag eq 'CMAKE_DETERMINE_COMPILER_ABI') { # ***TBD** TODO # act [(C ${CMAKE_ROOT}/Modules/CMakeCCompilerABI.c)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeTestCCompiler.cmake]71 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeTestCCompiler.cmake] } elsif ($tag eq 'CRT_VERSION') { # ***TBD** TODO # act [("${manifest_files}" manifest_version_list)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeVerifyManifest.cmake]1 src [Macro f subs] } elsif ($tag eq 'MATH') { # ***TBD** TODO # act [(EXPR _PACKAGE_HEADER_STRLENGTH "${_PACKAGE_HEADER_STRLENGTH} - 1")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CPackRPM.cmake]25 src [Macro _RPM_SPEC_HEADER subs] } elsif ($tag eq 'CHECK_VERSION') { # ***TBD** TODO # act [(${exe_files} "${manifest_version_list}")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeVerifyManifest.cmake]1 src [Macro f subs] } elsif ($tag eq 'CMAKE_DETERMINE_COMPILER_ID_VENDOR') { # ***TBD** TODO # act [(ASM${ASM_DIALECT})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeDetermineASMCompiler.cmake]119 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CMakeDetermineASMCompiler.cmake] } elsif ($tag eq 'ENABLE_TESTING') { # ***TBD** TODO # act [()] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake]97 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake] } elsif ($tag eq 'SITE_NAME') { # ***TBD** TODO # act [(SITE)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake]196 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake] } elsif ($tag eq 'GET_VS_VERSION_STRING') { # ***TBD** TODO # act [("${CMAKE_GENERATOR}" DART_CXX_NAME)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake]228 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake] } elsif ($tag eq 'BUILD_COMMAND') { # ***TBD** TODO # act [(MAKECOMMAND_DEFAULT_VALUE CONFIGURATION "\${CTEST_CONFIGURATION_TYPE}")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake]235 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTest.cmake] } elsif ($tag eq 'DEFINE_PROPERTY') { # ***TBD** TODO # act [(GLOBAL PROPERTY CTEST_TARGETS_ADDED BRIEF_DOCS "Internal property used by CTestTargets module." FULL_DOCS "Set by the CTestTargets module to track addition of testing targets." )] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTestTargets.cmake]57 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\CTestTargets.cmake] } elsif ($tag eq '_BOOST_CHECK_SPELLING') { # ***TBD** TODO # act [(Boost_ROOT)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake]572 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake] } elsif ($tag eq '_BOOST_COMPILER_DUMPVERSION') { # ***TBD** TODO # act [(_boost_COMPILER_VERSION)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake]775 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake] } elsif ($tag eq '_BOOST_PREPEND_LIST_WITH_THREADAPI') { # ***TBD** TODO # act [(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake]13 src [Macro COMPONENT subs] } elsif ($tag eq '_BOOST_SWAP_WITH_REALPATH') { # ***TBD** TODO # WARNING: tag [_BOOST_SWAP_WITH_REALPATH] NOT LISTED! act [(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake]32 src [Macro COMPONENT subs] } elsif ($tag eq '_BOOST_MARK_COMPONENTS_FOUND') { # ***TBD** TODO # act [(OFF)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake]1064 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindBoost.cmake] } elsif ($tag eq 'LOAD_CACHE') { # ***TBD** TODO # act [(${CABLE_BUILD_DIR} EXCLUDE BUILD_SHARED_LIBS LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH MAKECOMMAND CMAKE_INSTALL_PREFIX INCLUDE_INTERNALS CABLE_LIBRARY_PATH CABLE_EXECUTABLE_PATH)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCABLE.cmake]40 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCABLE.cmake] } elsif ($tag eq 'FIND_FILE') { # ***TBD** TODO # act [(CURSES_HAVE_CURSES_H curses.h )] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCurses.cmake]75 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindCurses.cmake] } elsif ($tag eq '_GTEST_APPEND_DEBUGS') { # ***TBD** TODO # act [(GTEST_LIBRARIES GTEST_LIBRARY)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTest.cmake]154 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTest.cmake] } elsif ($tag eq '_GTEST_FIND_LIBRARY') { # ***TBD** TODO # act [(GTEST_LIBRARY gtest-md gtest)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTest.cmake]138 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTest.cmake] } elsif ($tag eq '_GTK2_FIND_INCLUDE_DIR') { # ***TBD** TODO # act [(GTK2_GTK_INCLUDE_DIR gtk/gtk.h)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTK2.cmake]375 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTK2.cmake] } elsif ($tag eq '_GTK2_FIND_LIBRARY') { # ***TBD** TODO # act [(GTK2_GLIB_LIBRARY glib false true)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTK2.cmake]4 src [Macro _GTK2_component subs] } elsif ($tag eq '_GTK2_GET_VERSION') { # ***TBD** TODO # act [(GTK2_MAJOR_VERSION GTK2_MINOR_VERSION GTK2_PATCH_VERSION ${GTK2_GTK_INCLUDE_DIR}/gtk/gtkversion.h)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTK2.cmake]380 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGTK2.cmake] } elsif ($tag eq '_PROTOBUF_FIND_LIBRARIES') { # ***TBD** TODO # act [(PROTOBUF protobuf)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindProtobuf.cmake]167 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindProtobuf.cmake] } elsif ($tag eq '_QT4_QUERY_QMAKE') { # ***TBD** TODO # act [(QT_VERSION QTVERSION)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindQt4.cmake]493 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindQt4.cmake] } elsif ($tag eq 'ERROR_MESSAGE') { # ***TBD** TODO # act [( "Invalid Qt version string given: \"${QT_MIN_VERSION}\", expected e.g. \"3.1.5\"")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindQt3.cmake]205 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindQt3.cmake] } elsif ($tag eq 'FIND_IMAGEMAGICK_API') { # ***TBD** TODO # act [(Magick++ Magick++.h Magick++ CORE_RL_Magick++_ )] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindImageMagick.cmake]2 src [Macro component subs] } elsif ($tag eq 'FIND_IMAGEMAGICK_EXE') { # ***TBD** TODO # act [(${ImageMagick_FIND_COMPONENTS})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindImageMagick.cmake]9 src [Macro component subs] } elsif ($tag eq 'GET_DIRECTORY_PROPERTY') { # ***TBD** TODO # act [(incl INCLUDE_DIRECTORIES)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\SystemInformation.cmake]20 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\SystemInformation.cmake] } elsif ($tag eq 'INTERROGATE_MPI_COMPILER') { # ***TBD** TODO # act [(C ${try_libs})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindMPI.cmake]13 src [Macro lang subs] } elsif ($tag eq 'IS_FILE_EXECUTABLE') { # ***TBD** TODO # act [(MPI_C_COMPILER MPI_COMPILER_IS_EXECUTABLE)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindMPI.cmake]3 src [Macro lang subs] } elsif ($tag eq 'LINK_DIRECTORIES') { # ***TBD** TODO # act [(${VTK_LIBRARY_DIRS})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\UseVTK40.cmake]29 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\UseVTK40.cmake] } elsif ($tag eq 'LINK_LIBRARIES') { # ***TBD** TODO # act [(${WXWINDOWS_LIBRARIES})] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Use_wxWindows.cmake]53 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Use_wxWindows.cmake] } elsif ($tag eq 'OSG_FIND_LIBRARY') { # ***TBD** TODO # act [(OSG osg)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Findosg.cmake]51 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Findosg.cmake] } elsif ($tag eq 'OSG_FIND_PATH') { # ***TBD** TODO # act [(OSG osg/Version)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindOpenSceneGraph.cmake]88 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindOpenSceneGraph.cmake] } elsif ($tag eq 'OSG_MARK_AS_ADVANCED') { # ***TBD** TODO # act [(OSG)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindOpenSceneGraph.cmake]90 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindOpenSceneGraph.cmake] } elsif ($tag eq 'PKG_CHECK_MODULES') { # ***TBD** TODO # act [(PC_GNUTLS gnutls)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGnuTLS.cmake]39 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindGnuTLS.cmake] } elsif ($tag eq 'SANITYCHECKSDKANDDEPLOYTARGET') { # ***TBD** TODO # act [("${CMAKE_OSX_SYSROOT}" "${CMAKE_OSX_DEPLOYMENT_TARGET}")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Platform\Darwin.cmake]147 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\Platform\Darwin.cmake] } elsif ($tag eq 'SEPARATE_ARGUMENTS') { # ***TBD** TODO # act [(wxWidgets_CXX_FLAGS)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindwxWidgets.cmake]735 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindwxWidgets.cmake] } elsif ($tag eq 'SET_DIRECTORY_PROPERTIES') { # ***TBD** TODO # act [(PROPERTIES INCLUDE_DIRECTORIES "${DumpInformation_BINARY_DIR};${DumpInformation_SOURCE_DIR}")] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\SystemInformation.cmake]21 src [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\SystemInformation.cmake] } elsif ($tag eq 'TRY_REGULAR_COMPILER') { # ***TBD** TODO # act [(C regular_compiler_worked)] in [C:\Program Files (x86)\CMake 2.8\share\cmake-2.8\Modules\FindMPI.cmake]17 src [Macro lang subs] } elsif ($tag eq 'ENABLE_LANGUAGE') { # ***TBD** TODO } else { if (!defined $action_is_uncased{$tag}) { $action_is_uncased{$tag} = 1; prtw("WARNING: Action NOT CASED! [$tag] act [$action] [$bfile]$lnn\n"); } else { $warnings_avoided++; } } } sub full_opts_line($) { my ($line) = shift; my $len = length($line); my $inquot = 0; my $inbrac = 0; my ($i,$ch,$qc,$pc,$pc2); $ch = ''; $pc = ''; for ($i = 0; $i < $len; $i++) { $pc2 = $pc; $pc = $ch; $ch = substr($line,$i,1); if ($inbrac) { if ($inquot) { # $inquot = 0 if (($ch eq $qc)&&($pc ne "\\")); $inquot = 0 if ( ($ch eq $qc) && ( ($pc ne "\\") || ( ($pc eq "\\")&&($pc2 eq "\\") ) ) ); } elsif ($ch eq '"') { # &&($pc ne "\\")) { $inquot = 1; $qc = $ch; } elsif ($ch eq ')') { $inbrac--; if ($inbrac == 0) { return 1; } } } else { if ($inquot) { #$inquot = 0 if (($ch eq $qc)&&($pc ne "\\")); $inquot = 0 if ( ($ch eq $qc) && ( ($pc ne "\\") || ( ($pc eq "\\")&&($pc2 eq "\\") ) ) ); } elsif ($ch eq '"') { # &&($pc ne "\\")) { $inquot = 1; $qc = $ch; } elsif ($ch eq '(') { $inbrac++; } } } return 0; } sub split_opts_line($) { my ($line) = shift; my $len = length($line); my $inquot = 0; my $inbrac = 0; my ($i,$ch,$qc,$command,$hadsp,$pc,$pc2); my @arr = (); # got nothing so far $command = ''; # start the collection $hadsp = 0; # had no space yet for ($i = 0; $i < $len; $i++) { $ch = substr($line,$i,1); if ($ch eq '(') { last; # found first '(' } elsif ( !($ch =~ /\s/) ) { $command .= $ch; } else { # have a SPACE if (length($command)) { # already had some non-space - trailing space # should check if the next sig char is the '(' } # else have not yet started command, # so ignore this beginning space } } if (($ch ne '(')||(length($command)==0)) { prtw("WARNING: Option line did not conform! [$line]\n"); return \@arr; } push(@arr,$command); # push first item 'OPTION' or 'option' $command = ''; # collect space separated items, skipping spaces in quoted strings $ch = ''; $pc = ''; for (; $i < $len; $i++) { $pc2 = $pc; $pc = $ch; $ch = substr($line,$i,1); if ($inbrac) { if ($inquot) { $command .= $ch; # $inquot = 0 if (($ch eq $qc)&&($pc ne "\\")); $inquot = 0 if ( ($ch eq $qc) && ( ($pc ne "\\") || ( ($pc eq "\\")&&($pc2 eq "\\") ) ) ); } else { if ($ch =~ /\s/) { push(@arr,$command) if (length($command)); $command = ''; } else { # not a space if ($ch eq ')') { $inbrac--; if ($inbrac == 0) { last; } } else { # not end bracket $command .= $ch; if ($ch eq '"') { # &&($pc ne "\\")) { $inquot = 1; $qc = $ch; } } } } } else { if ($inquot) { # $inquot = 0 if (($ch eq $qc)&&($pc ne "\\")); $inquot = 0 if ( ($ch eq $qc) && ( ($pc ne "\\") || ( ($pc eq "\\")&&($pc2 eq "\\") ) ) ); } elsif ($ch eq '"') { # &&($pc ne "\\")) { $inquot = 1; $qc = $ch; } elsif ($ch eq '(') { $inbrac++; } } } push(@arr,$command) if (length($command)); return \@arr; } sub process_cmake_OPTION_lines($) { my $rh = shift; my ($rlines,$in); $in = ${$rh}{"BASE_FILE"}; $rlines = ${$rh}{"BASE_LINES"}; ###my @options = (); ###${$rh}{'CMAKE_OPTIONS'} = \@options; my $rops = ${$rh}{'CMAKE_OPTIONS'}; my ($cnt,$lnn,$i,$i2,$line,$tline,$tmp); my ($ra,$len,$option,$message,$default); my $mino = 0; my $minm = 0; $cnt = scalar @{$rlines}; $in =~ s/^\.(\\|\/)//; $lnn = sprintf("%5d", $cnt); $in .= ' ' while (length($in) < 8+1+3); prt("[v9] Got $lnn lines, from [$in] to process...\n") if (VERB9()); for ($i = 0; $i < $cnt; $i++) { $total_lines++; $i2 = $i + 1; $line = ${$rlines}[$i]; $total_bytes += length($line); chomp $line; $tline = trim_all($line); if ($tline =~ /^option\s*\(/i) { # seek OPTION(...) line while (($i2 < $cnt)&&(!full_opts_line($tline))) { $total_lines++; $i++; $i2 = $i + 1; $tmp = ${$rlines}[$i]; $total_bytes += length($tmp); $tline .= ' '; $tline = trim_all($tmp); } prt("[v9]:$i2: [$tline]\n") if (VERB9()); $ra = split_opts_line($tline); $len = scalar @{$ra}; if ($len >= 2) { $tmp = ${$ra}[0]; $option = ${$ra}[1]; $message = 'NO MESSAGE'; if ($len > 2) { $message = ${$ra}[2]; } $default = 'OFF'; if ($len > 3) { $default = ${$ra}[3]; } ###push(@options, [$option, $message, $default]); push(@{$rops}, [$option, $message, $default]); if (VERB9()) { prt("[v9] $option $message $default\n"); #foreach $tmp (@{$ra}) { # prt("$tmp "); #} #prt("\n"); } } else { prtw("$pgmname:WARNING: Line $i2 did not SPLIT correctly! [$tline] file $in\n"); } } } # ${$rh}{"OPTIONS"} = \@options; } #sub add_if_tags($$) { # my ($rh,$txt) = @_; # my $riftags = ${$rh}{'CMAKE_IFTAGS'}; # my $bfile = ${$rh}{"BASE_FILE"}; # my $lnn = ${$rh}{"ACT_LNN"}; # #${$riftags}{$txt} = 1; # my $len = length($txt); # my ($i,$ch,$tag,%mods,$ra); # $tag = ''; # %mods = (); # # if(${CMAKE_VERSION} VERSION_GREATER 2.8.4) # if ($txt =~ /\W*\$\{CMAKE_VERSION\}/) { # $tag = 'CMAKE_VERSION'; # ${$riftags}{$tag} = [] if (!defined ${$riftags}{$tag}); # $ra = ${$riftags}{$tag}; # push(@{$ra},[{%mods},$bfile,$lnn]); # return; # } elsif ($txt =~ /\W*\$\{MSVC_VERSION\}/) { # # if (${MSVC_VERSION} EQUAL 1600) # $tag = 'MSVC_VERSION'; # ${$riftags}{$tag} = [] if (!defined ${$riftags}{$tag}); # $ra = ${$riftags}{$tag}; # push(@{$ra},[{%mods},$bfile,$lnn]); # return; # } elsif ($txt =~ /\$ENV\{(\w+)\}/) { # # if(NOT "$ENV{BUILD_ID}" STREQUAL "") # $tag = "ENV(".$1.")"; # ${$riftags}{$tag} = [] if (!defined ${$riftags}{$tag}); # $ra = ${$riftags}{$tag}; # push(@{$ra},[{%mods},$bfile,$lnn]); # return; # } # for ($i = 0; $i < $len; $i++) { # $ch = substr($txt,$i,1); # if ($ch =~ /\w/) { # $tag .= $ch; # } elsif (length($tag)) { # if (($tag =~ /^AND$/i)||($tag =~ /^OR$/i)||($tag =~ /^NOT$/i)||($tag =~ /^STREQUAL$/i)) { # # forget these # $mods{$tag} = 1; # } else { # ${$riftags}{$tag} = [] if (!defined ${$riftags}{$tag}); # $ra = ${$riftags}{$tag}; # push(@{$ra},[{%mods},$bfile,$lnn]); # %mods = (); # } # $tag = ''; # } # } # #${$riftags}{$tag} = [@mods]; # if (length($tag)) { # ${$riftags}{$tag} = [] if (!defined ${$riftags}{$tag}); # $ra = ${$riftags}{$tag}; # push(@{$ra},[{%mods},$bfile,$lnn]); # } #} sub process_macro($) { my $rh = shift; my $bfile = ${$rh}{"BASE_FILE"}; my $csrc = ${$rh}{'CURR_LINE_SOURCE'}; my $rma = ${$rh}{'CMAKE_MACROS'}; my $tag = ${$rh}{"ACT_TAG"}; my $action = ${$rh}{"ACT_ACT"}; my $lnn = ${$rh}{"ACT_LNN"}; my $tline = ${$rh}{"ACT_LINE"}; my $i = ${$rh}{"ACT_I"}; my $lctag = lc($tag); my ($rm); $tag = ${$rh}{'CURR_FOUND_MACRO'}; if (defined ${$rma}{$tag}) { $rm = ${$rma}{$tag}; } elsif (defined ${$rma}{$lctag}) { $tag = $lctag; $rm = ${$rma}{$tag}; } else { if (!defined $macros_not_found{$tag} && !defined $macros_not_found{$lctag}) { $macros_not_found{$tag} = 1; $macros_not_found{$lctag} = 1; prtw("WARNING: Macro matching [$tag] and [$lctag] NOT FOUND! in 'CMAKE_MACROS [$bfile]$lnn\n"); } return; } ### my $rm = ${$rma}{$tag}; my $msubs = ${$rm}[0]; my @sarr = space_split($msubs); my %subs = (); my ($tmp,$scnt,$msg); $scnt = 0; foreach $tmp (@sarr) { $subs{$tmp} = 1; $scnt++; } my $macro = ${$rm}[1]; my $act = clean_action($action); my @arr = space_split($act); my $cnt = scalar @arr; my $name = $arr[0]; my $ARGN = ''; for ($i = 0; $i < $cnt; $i++) { if ($i < $scnt) { $tmp = $sarr[$i]; $subs{$tmp} = $arr[$i]; $macro =~ s/\$\{$tmp\}/$arr[$i]/g; } else { $ARGN .= ' ' if (length($ARGN)); $ARGN .= $arr[$i]; } } $macro =~ s/\$\{ARGN\}/$ARGN/g if (length($ARGN)); $msg = ''; foreach $tmp (@sarr) { $msg .= ' ' if (length($msg)); $msg .= "$tmp="; $msg .= $subs{$tmp}; } # prt("[v9] Macro $tag, ms [$msubs] - $cnt [$act]\n") if ($dbg_04 || VERB9()); if ($dbg_04 || VERB9()) { prt("[v9] Macro $tag, ms [$msubs] - $cnt $msg ARGN=$ARGN\n"); prt("[v9] Macro TEXT [$macro]\n"); } } my $max_out_line = 95; sub max_out_line($) { my $line = shift; my $len = length($line); if ($len > $max_out_line) { $line = substr($line,0,45)."...".substr($line,$len-45); } return $line; } sub process_cmake_list($) { my $rh = shift; my $bfile = ${$rh}{"BASE_FILE"}; my $rlines = ${$rh}{"BASE_LINES"}; my $cursrc = ${$rh}{'CURR_LINE_SOURCE'}; $bfile .= ":$cursrc" if ($bfile ne $cursrc); my $lcnt = scalar @{$rlines}; prt("[v9] Got $lcnt lines, from $bfile\n") if (VERB9()); my ($i,$lnn,$line,$trline,$len,$ch,$j,$tag,$test,$fnd,@braces,$action,$inquot,$pc,$pc2,$bq); my ($rma,$key,$msg,$tmp,$tail,$brcnt); #my @ifstack = (); #my %iftags = (); #my @if_stack = (); #${$rh}{'CURR_IF_STACK'} = \@if_stack; my $rifstk = ${$rh}{'CURR_IF_STACK'}; @{$rifstk} = (); # clear stack ${$rh}{'CURR_IN_IF'} = 0; # zero IF counter my $riftags = ${$rh}{'CMAKE_IFTAGS'}; ${$rh}{"ACT_LCNT"} = $lcnt; $ch = ''; $pc = ''; for ($i = 0; $i < $lcnt; $i++) { $lnn = $i + 1; $line = ${$rlines}[$i]; # extract a LINE chomp $line; $trline = trim_all($line); $len = length($trline); next if ($len == 0); # skip if trimmed line is blank next if ($trline =~ /^\#/); # skip if a comment line $tag = ''; $line = ''; # start FULL line accumulation # get FIRST item on the line at the tag (directive) $ch = ''; $pc = ''; for ($j = 0; $j < $len; $j++) { $pc2 = $pc; $pc = $ch; $ch = substr($trline,$j,1); $line .= $ch; last if ($ch =~ /\W/); $tag .= $ch; } $tag = uc($tag); # see if the directive is in the list of directives # continue eating spaces for (; $j < $len; $j++) { $pc2 = $pc; $pc = $ch; $ch = substr($trline,$j,1); last if ($ch =~ /\S/); } # this should be the BEGINNING of a directive (... until ...) end if ($ch eq '(') { $line .= $ch; # add to LINE @braces = (); push(@braces,$ch); $brcnt = scalar @braces; $j++; $action = $ch; # start the action $inquot = 0; # continue on the line - skip over quote "..." $pc = ''; $tail = ''; for (; $j < $len; $j++) { $pc2 = $pc; $pc = $ch; $ch = substr($trline,$j,1); if ($brcnt == 0) { last if ($ch eq '#'); if ($ch =~ /\s/) { $tail .= $ch if (length($tail)); } else { $tail .= $ch; } next; } $action .= $ch; # add character to 'action', within braces $line .= $ch; if ($inquot) { # $inquot = 0 if (($ch eq '"')&&($pc ne "\\")); $inquot = 0 if ( ($ch eq '"') && ( ($pc ne "\\") || ( ($pc eq "\\")&&($pc2 eq "\\") ) ) ); } else { if ($ch eq '(') { push(@braces,$ch); $brcnt = scalar @braces; } elsif ($ch eq ')') { if (@braces) { pop @braces; # pop this brace } else { $msg = "WARNING: Encountered ')' with none on stack! $line [$bfile]$lnn"; prtw("$msg\n"); } $brcnt = scalar @braces; } elsif ($ch eq '"') { # &&($pc ne "\\")) { $inquot = 1; $bq = $j; } } } # done the line # 20120427 - BUT FOUND LINE WRAP WITH QUOTES LIKE # FILE(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f " # PROGRAM TESTFortran # PRINT *, 'Hello' # END # ") #if ($inquot) { #$tmp = max_out_line($trline); #$msg = "Ended line in QUOTES! ["; #$len = length($msg); #$msg .= "$tmp] [$bfile]$lnn"; #$msg .= " src [$csrc]" if ($bfile ne $csrc); #if ($bq < 80) { #$msg .= "\n"; #$msg .= ($len + $bq) x ' '; #$msg .= "<- BEGIN HERE"; #} #prtw("WARNING: $msg\n"); #} #$inquot = 0; # 20120425 - NEW BEHAVIOUR - end of line == end of quotes $brcnt = scalar @braces; while ($brcnt) { # but are in OPEN braces, so continue to NEXT $i++; $action .= ' '; if ($i < $lcnt) { $lnn = $i + 1; $trline = ${$rlines}[$i]; # get NEXT line chomp $trline; $trline = trim_all($trline); $len = length($trline); # process this NEXT line, again skipping quotes $ch = ''; $pc = ''; for ($j = 0; $j < $len; $j++) { $pc2 = $pc; $pc = $ch; $ch = substr($trline,$j,1); $action .= $ch; $line .= $ch; if ($inquot) { $inquot = 0 if ( ($ch eq '"') && ( ($pc ne "\\") || ( ($pc eq "\\")&&($pc2 eq "\\") ) ) ); # $inquot = 0 if (($ch eq '"')&&($pc ne "\\")); } else { if ($ch eq '(') { push(@braces,$ch); $brcnt = scalar @braces; } elsif ($ch eq ')') { if (@braces) { pop @braces; } else { $msg = "WARNING: Encountered ')' with none on stack! $line [$bfile]$lnn"; prtw("$msg\n"); } $brcnt = scalar @braces; } elsif ($ch eq '"') { # &&($pc ne "\\")) { $inquot = 1; } } } } else { $tmp = max_out_line($line); $msg = "WARNING: Ran out of lines in a brace! [$tmp] [$bfile]$lnn"; prtw("$msg\n"); last; } } if ($inquot) { $tmp = max_out_line($line); $msg = "WARNING: Ended lines in QUOTES! [$tmp] [$bfile]$lnn"; prtw("$msg\n"); } if (length($tail)) { $tmp = max_out_line($line); $msg = "WARNING: Got out-of-brace [$tail] WHAT IS THIS? [$tmp] [$bfile]$lnn"; prtw("$msg\n"); } } elsif ($ch eq '@') { # example - ALSO NOTE TRAILING comment '# list' # set(CUDA_NVCC_FLAGS @CUDA_NVCC_FLAGS@ ;; @CUDA_WRAP_OPTION_NVCC_FLAGS@) # list # @CUDA_NVCC_FLAGS_CONFIG@ # set(nvcc_flags @nvcc_flags@) # list $line .= $ch; # add to LINE for (; $j < $len; $j++) { $pc2 = $pc; $pc = $ch; $ch = substr($trline,$j,1); $line .= $ch; last if ($ch eq '@'); } # ***TBD*** What to do with THIS?????? next; } else { $msg = "WARNING: First char NOT '(' nor '\@'! [$line] [$bfile]$lnn"; prtw("$msg\n"); next; } ${$rh}{"ACT_TAG"} = $tag; ${$rh}{"ACT_ACT"} = $action; ${$rh}{"ACT_LNN"} = $lnn; ${$rh}{"ACT_LINE"} = $line; ${$rh}{"ACT_I"} = $i; if ($line =~ /^if\s*\((.*)\)/i) { # FOUND AN IF ${$rh}{'CURR_IN_IF'}++; # bump IF counter $tag = $1; # my $riftags = ${$rh}{'CMAKE_IFTAGS'} = \%if_tags; prt("$lnn: IF($tag)\n") if ($dbg_01 || VERB9()); #push(@ifstack,[$tag,$lnn]); push(@{$rifstk},[$tag,$lnn]); if (length($tag)) { # $iftags{$tag} = 1; ### add_if_tags($rh,$tag); # ${$riftags}{$tag} = 1; } else { prtw("WARNING: $lnn: Got an IF with NO tag! [$line]! [$bfile]$lnn\n"); } } elsif ($line =~ /^else\s*\((.*)\)/i) { # FOUND AN ELSE $tag = $1; prt("$lnn: ELSE($tag)\n") if ($dbg_01 || VERB9()); } elsif ($line =~ /^elseif\s*\((.*)\)/i) { # FOUND ELSEIF $tag = $1; prt("$lnn: ELSEIF($tag)\n") if ($dbg_01 || VERB9()); } elsif ($line =~ /^endif\s*\((.*)\)/i) { # FOUND ENDIF ${$rh}{'CURR_IN_IF'}--; # decrement IF counter $tag = $1; prt("$lnn: ENDIF($tag)\n") if ($dbg_01) || VERB9(); if (@{$rifstk}) { pop @{$rifstk}; } } else { # NOT IF, ELSE, ELSEIF, ENDIF $fnd = 0; foreach $test (@cmake_actions) { if ($test eq $tag) { $fnd = 1; last; } } if (defined $cpack_actions{$tag}) { $cpack_actions{$tag}->($rh); } elsif ($fnd) { #prt("Action [$tag] $action\n"); process_action($rh); $i = ${$rh}{"ACT_I"}; # potentially updated line number } else { $rma = ${$rh}{'CMAKE_MACROS'}; foreach $key (keys %{$rma}) { if ($key eq $tag) { $fnd = 1; ${$rh}{'CURR_FOUND_MACRO'} = $key; last; } if (lc($key) eq lc($tag)) { $fnd = 1; ${$rh}{'CURR_FOUND_MACRO'} = $key; last; } } if ($fnd) { # found action is a MACRO - see if I can EXPAND the macro using the arguments process_macro($rh); } else { if (!defined $unlisted_tags{$tag}) { $unlisted_tags{$tag} = 1; $msg = ''; if ($add_searched_debug) { $msg = "\nSearched: "; my (@tarr,$tcnt); @tarr = keys(%cpack_actions); $tcnt = scalar @tarr; $msg .= "\ncpack_actions: $tcnt "; foreach $tmp (@tarr) { $msg .= "$tmp "; } $tcnt = scalar @cmake_actions; $msg .= "\ncmake_actions: $tcnt "; foreach $tmp (@cmake_actions) { $msg .= "$tmp "; } @tarr = keys(%cpack_actions); $tcnt = scalar @tarr; $msg .= "\nCMAKE_MACROS: $tcnt "; foreach $key (@tarr) { $msg .= "$key "; } } prtw("WARNING: tag NOT LISTED! [$tag] act [$action] in [$bfile]$lnn $msg\n"); } else { $unlisted_tags{$tag}++; } } } } } if (@{$rifstk}) { prtw("WARNING: Still entries in IF stack! [$bfile]$lnn\n"); } process_cmake_OPTION_lines($rh); } ### DO MACRO SUBS ### sub do_macro_subs($) { my $rh = shift; my $rma = ${$rh}{'CMAKE_MACROS'}; my @arr = sort keys(%{$rma}); #my @arr = sort keys(%macros); my ($mnm,$args,$macs,$rm); foreach $mnm (@arr) { # $rm = $macros{$mnm}; # ${$rma}{$mnm}; $rm = ${$rma}{$mnm}; $args = ${$rm}[0]; $macs = ${$rm}[1]; my @lines = split("\n", $macs); # ${$rm}{$mnm}); ${$rh}{"BASE_LINES"} = \@lines; ${$rh}{'CURR_LINE_SOURCE'} = "Macro $mnm"; process_cmake_list($rh); } } sub do_subdirectories($) { my $rh = shift; # ADD_SUBDIRECTORY # my %subdirs = (); # ${$rh}{'CMAKE_SUBDIRS'} = \%subdirs; #my %subs_done = (); # ${$rh}{'CMAKE_SUBSDONE'} = \%subs_done; my $rsh = ${$rh}{'CMAKE_SUBDIRS'}; my $rsd = ${$rh}{'CMAKE_SUBSDONE'}; my @arr = keys(%{$rsh}); my $max = scalar @arr; my ($i,$sd,$ff,$key,$rsa); for ($i = 0; $i < $max; $i++) { $key = $arr[$i]; $rsa = ${$rsh}{$key}; # 0 1 # push(@{$rsubs},[$item1,$ff]); $sd = ${$rsa}[0]; $ff = ${$rsa}[1]; if (!defined ${$rsd}{$ff}) { ${$rsd}{$ff} = 1; process_in_file($ff,$rh); } } } sub process_in_file($$) { my ($inf,$rh) = @_; my $rfh = ${$rh}{'CMAKE_FILES_LOADED'}; if (defined ${$rfh}{$inf}) { return $rh; } ${$rfh}{$inf} = 1; # set as DONE if (! open INF, "<$inf") { pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); } my @lines = ; close INF; my $lncnt = scalar @lines; prt("Processing $lncnt lines, from [$inf]...\n") if (VERB2()); $total_file_lines += $lncnt; $total_files++; my ($name,$dir) = fileparse($inf); ${$rh}{'PROJECT_SOURCE_DIR'} = $dir; ${$rh}{"BASE_FILE"} = $inf; ${$rh}{'CURR_LINE_SOURCE'} = $inf; ${$rh}{"BASE_LINES"} = \@lines; my $rfa = ${$rh}{'CMAKE_FILES'}; push(@{$rfa},$inf); process_cmake_list($rh); # should this be on a per FILE basis, or at the END # do_macro_subs($rh); do_subdirectories($rh); return $rh; } sub process_in_dir($$) { my ($dir,$rh) = @_; if (! opendir(DIR, $dir) ) { pgm_exit(1,"ERROR: Unable to open directory [$dir]\n"); } my @files = readdir(DIR); closedir(DIR); my ($bfile); $dir .= $PATH_SEP if ( !($dir =~ /(\\|\/)$/) ); $bfile = $dir."CMakeLists.txt"; if (-f $bfile) { ${$rh}{'PRIMARY_CMAKE_FILE'} = $bfile; ${$rh}{'PRIMARY_CMAKE_DIR'} = $dir; return process_in_file($bfile,$rh); } else { prtw("WARNING: Directory [$dir] does NOT contain a 'CMakeLists.txt' file!\n"); } return $rh; } sub show_cmake_options($) { my $rh = shift; my ($in,$roptions); $in = ${$rh}{'PRIMARY_CMAKE_FILE'}; $roptions = ${$rh}{"CMAKE_OPTIONS"}; my ($i,$ra,$len,$option,$message,$default,$cnt); my $mino = 0; my $minm = 0; $cnt = scalar @{$roptions}; $total_options += $cnt; $mino = 0; $minm = 0; if ($cnt) { prt("\nOPTION: Found $cnt 'OPTION' items in [$in]\n"); for ($i = 0; $i < $cnt; $i++) { # 0 1 2 # push(@options, [$option, $message, $default]); $option = ${$roptions}[$i][0]; $message = ${$roptions}[$i][1]; $default = ${$roptions}[$i][2]; $len = length($option); $mino = $len if ($len > $mino); $len = length($message); $minm = $len if ($len > $minm); } for ($i = 0; $i < $cnt; $i++) { # 0 1 2 # push(@options, [$option, $message, $default]); $option = ${$roptions}[$i][0]; $message = ${$roptions}[$i][1]; $default = ${$roptions}[$i][2]; $option .= ' ' while (length($option) < $mino); $message .= ' ' while (length($message) < $minm); prt("$option $message $default\n"); } } else { prt("[v9] Found NO options!\n") if (VERB9()); } } sub show_install_actions($) { my $rh = shift; my $in = ${$rh}{'PRIMARY_CMAKE_FILE'}; #my $cnt = scalar @install_actions; # my @install_actions = (); # ${$rh}{'CMAKE_INSTALLS'} = \@install_actions; my $ria = ${$rh}{'CMAKE_INSTALLS'}; # push(@install_actions,[$lnn,$act]); #push(@{$ria},[$lnn,$act]); my $cnt = scalar @{$ria}; # 0 1 # push(@install_actions,[$lnn,$act]); prt("\nINSTALLL: Found $cnt 'INSTALL' actions in [$in]\n"); my ($act,$lnn,$ra,$i); for ($i = 0; $i < $cnt; $i++) { # $ra = $install_actions[$i]; $ra = ${$ria}[$i]; $lnn = ${$ra}[0]; $act = ${$ra}[1]; prt("$lnn $act\n"); } } sub show_set_lists($) { my $rh = shift; my $in = ${$rh}{'PRIMARY_CMAKE_FILE'}; ## my %set_macros = (); ## ${$rh}{'CMAKE_SETMACROS'} = \%set_macros; ## my @arr = sort keys(%set_macros); my $rsmh = ${$rh}{'CMAKE_SETMACROS'}; my @arr = sort keys(%{$rsmh}); my $cnt = scalar @arr; prt("\nSET: Found $cnt 'SET' lists in [$in]\n"); my ($var,$ra); $cnt = 0; foreach $var (@arr) { $ra = ${$rsmh}{$var}; $cnt++; prt("$cnt: $var = [".join(" ",@{$ra})."]\n"); } } sub show_list_sets($) { my $rh = shift; my $in = ${$rh}{'PRIMARY_CMAKE_FILE'}; my $rli = ${$rh}{'CMAKE_LISTS'}; # $ok = is_in_list_operations($item1); my @arr = sort keys(%{$rli}); my $cnt = scalar @arr; prt("\nLIST: Found $cnt 'LIST' lists in [$in]\n"); my ($key,$ra,$icnt); $cnt = 0; foreach $key (@arr) { $ra = ${$rli}{$key}; $cnt++; $icnt = scalar @{$ra}; prt("$cnt:$icnt: $key = [".join(" ",@{$ra})."]\n"); } } sub show_binary_items($) { my $rh = shift; my $in = ${$rh}{'PRIMARY_CMAKE_FILE'}; my $rlibs = ${$rh}{'CMAKE_LIBS'}; my $rexes = ${$rh}{'CMAKE_EXES'}; my @earr = sort keys(%{$rexes}); my @larr = sort keys(%{$rlibs}); my $ecnt = scalar @earr; my $lcnt = scalar @larr; prt("\nADD_[BIN]: Found $ecnt 'EXECUTABLE' $lcnt 'LIBRARY' in [$in]\n"); my ($key,$ra,$icnt); prt(" EXECUTABLE: $ecnt\n") if ($ecnt); $ecnt = 0; foreach $key (@earr) { $ra = ${$rexes}{$key}; $ecnt++; $icnt = scalar @{$ra}; prt("$ecnt:$icnt: $key = [".join(" ",@{$ra})."]\n"); } prt(" LIBRARY: $lcnt\n") if ($lcnt); $lcnt = 0; foreach $key (@larr) { $ra = ${$rlibs}{$key}; $lcnt++; $icnt = scalar @{$ra}; prt("$lcnt:$icnt: $key = [".join(" ",@{$ra})."]\n"); } } #sub show_if_tags($) { # my $rh = shift; # my $riftags = ${$rh}{'CMAKE_IFTAGS'}; # my @arr = keys(%{$riftags}); # my $itcnt = scalar @arr; # prt("\nGot $itcnt IF tags...\n"); # $itcnt = 0; # my ($tag,$ra,$ff,$lnn,$ra2,$msg,$min,$len); # $min = 0; # foreach $tag (sort @arr) { # $len = length($tag); # $min = $len if ($len > $min); # } # # $ra = ${$riftags}{$tag}; # # push(@{$ra},[{%mods},$bfile,$lnn]); # foreach $tag (sort @arr) { # $itcnt++; # $ra = ${$riftags}{$tag}; # $msg = ''; # foreach $ra2 (@{$ra}) { # $ff = ${$ra2}[1]; # $lnn = ${$ra2}[2]; # $msg .= ' ' if (length($msg)); # $msg .= "$ff($lnn)"; # } # # $tag .= ' ' while (length($tag) < $min); # prt("$itcnt: $tag $msg\n"); # } #} sub show_files_done($) { my $rh = shift; my $rfa = ${$rh}{'CMAKE_FILES'}; my ($inf,$cnt); #push(@{$rfa},$inf); $cnt = scalar @{$rfa}; prt("\nProcessed $cnt files...\n"); $cnt = 0; foreach $inf (@{$rfa}) { $cnt++; prt("$cnt: $inf\n"); } } sub load_cmake_mod_dir($$) { my ($dir,$rh) = @_; # $cmake_moddir,$$rel_hash); if (! opendir(DIR, $dir) ) { pgm_exit(1,"ERROR: Unable to open directory [$dir]\n"); } my @files = readdir(DIR); closedir(DIR); my ($file,$ff); $dir .= $PATH_SEP if (!($dir =~ /(\\|\/)$/)); my $svverb = $verbosity; $verbosity = 9 if ($dbg_08); foreach $file (@files) { next if (($file eq ".")||($file eq "..")); next if (!($file =~ /\.cmake$/)); $ff = $dir.$file; path_form(\$ff); if (-f $ff) { process_in_file($ff,$rh); } else { pgm_exit(1,"ERROR: Stupid IMPOSSIBILITY! [$ff] DOES NOT EXIST!\n"); } } $verbosity = $svverb; } sub load_installed_cmake($) { my $rh = shift; scan_cmake_install_paths($rh); my $rif = ${$rh}{'CMAKE_INSTALLED_FILES'}; my $cnt = scalar @{$rif}; prt("Got $cnt files to load...\n"); my ($ff); foreach $ff (@{$rif}) { process_in_file($ff,$rh); } } ######################################### ### MAIN ### parse_args(@ARGV); ### prt( "$pgmname: in [$cwd]: Hello, World...\n" ); my $ref_hash = get_cmake_ref_hash(); if ($load_installed_cmake) { load_installed_cmake($ref_hash); pgm_exit(1,"TEMP EXIST"); } if (-f $in_file) { my ($n,$d) = fileparse($in_file); $cmake_moddir = $d."CMakeModules"; if ((-d $cmake_moddir) && $inc_all_cmake) { # load CMakeModule directory load_cmake_mod_dir($cmake_moddir,$$ref_hash); } elsif ($inc_all_cmake) { prtw("WARNING: No 'CMakeModules' directory EXISTS for this file! [$cmake_moddir]\n"); } ${$ref_hash}{'PRIMARY_CMAKE_DIR'} = $d; ${$ref_hash}{'PRIMARY_CMAKE_FILE'} = $in_file; process_in_file($in_file,$ref_hash); #$ref_hash = process_in_file($in_file); } elsif (-d $in_file) { my $d = $in_file; fix_directory(\$d); $cmake_moddir = $d."CMakeModules"; if ($inc_all_cmake) { if (-d $cmake_moddir) { # load CMakeModule directory load_cmake_mod_dir($cmake_moddir,$ref_hash); } else { prtw("WARNING: No [$cmake_moddir] EXISTS!\n"); } } process_in_dir($in_file,$ref_hash); #$ref_hash = process_in_dir($in_file); } # should this be on a per FILE basis, or at the END do_macro_subs($ref_hash); prt("Processed totol $total_file_lines lines from $total_files CMakeLists.txt files...\n"); show_cmake_options($ref_hash) if ($show_options || $show_all); show_install_actions($ref_hash) if ($show_installs || $show_all); show_set_lists($ref_hash) if ($show_sets || $show_all); show_list_sets($ref_hash) if ($show_lists || $show_all); show_binary_items($ref_hash) if ($show_binaries || $show_all); ### show_if_tags($ref_hash) if ($show_if_tags || $show_all); show_files_done($ref_hash) if (VERB1()); prt("Processed totol $total_file_lines lines from $total_files CMakeLists.txt files...\n"); 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 =~ /^b/) { $show_binaries = 1; prt("Set show 'ADD_EXECUTABLE' and 'ADD_LIBRARY' and sources.\n") if (VERB1()); } elsif ($sarg =~ /^i/) { $show_installs = 1; prt("Set show 'INSTALL' actions.\n") if (VERB1()); #} elsif ($sarg =~ /^I/) { # $show_if_tags = 1; # prt("Set show 'IF' tags.\n") if (VERB1()); } elsif ($sarg =~ /^s/) { $show_sets = 1; prt("Set show 'SET' lists.\n") if (VERB1()); } 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/) { $show_lists = 1; prt("Set show 'LIST' sets.\n") if (VERB1()); } elsif ($sarg =~ /^l/) { $load_log = 1; prt("Set to load log at end.\n") if (VERB1()); } elsif ($sarg =~ /^o/) { $show_options = 1; prt("Set to show 'OPTION' items.\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 ((length($in_file) == 0) && $debug_on) { $in_file = $def_file; $load_log = 2; #$show_binaries = 1; #$show_lists = 1; #$show_sets = 1; set_warn_all(); } if (length($in_file) == 0) { pgm_exit(1,"ERROR: No input files found in command!\n"); } if ((! -d $in_file) && (! -f $in_file)) { pgm_exit(1,"ERROR: Unable to find in directory or file [$in_file]! Check name, location...\n"); } } sub get_LIST_info() { my $txt = < filename variable) file(STRINGS filename variable [LIMIT_COUNT num] [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes] [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes] [NEWLINE_CONSUME] [REGEX regex] [NO_HEX_CONVERSION]) file(GLOB variable [RELATIVE path] [globbing expressions]...) file(GLOB_RECURSE variable [RELATIVE path] [FOLLOW_SYMLINKS] [globbing expressions]...) file(RENAME ) file(REMOVE [file1 ...]) file(REMOVE_RECURSE [file1 ...]) file(MAKE_DIRECTORY [directory1 directory2 ...]) file(RELATIVE_PATH variable directory file) file(TO_CMAKE_PATH path result) file(TO_NATIVE_PATH path result) file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout] [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS] [EXPECTED_MD5 sum]) file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout] [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]) WRITE will write a message into a file called 'filename'. It overwrites the file if it already exists, and creates the file if it does not exist. APPEND will write a message into a file same as WRITE, except it will append it to the end of the file READ will read the content of a file and store it into the variable. It will start at the given offset and read up to numBytes. If the argument HEX is given, the binary data will be converted to hexadecimal representation and this will be stored in the variable. MD5, SHA1, SHA224, SHA256, SHA384, and SHA512 will compute a cryptographic hash of the content of a file. STRINGS will parse a list of ASCII strings from a file and store it in a variable. Binary data in the file are ignored. Carriage return (CR) characters are ignored. It works also for Intel Hex and Motorola S-record files, which are automatically converted to binary format when reading them. Disable this using NO_HEX_CONVERSION. LIMIT_COUNT sets the maximum number of strings to return. LIMIT_INPUT sets the maximum number of bytes to read from the input file. LIMIT_OUTPUT sets the maximum number of bytes to store in the output variable. LENGTH_MINIMUM sets the minimum length of a string to return. Shorter strings are ignored. LENGTH_MAXIMUM sets the maximum length of a string to return. Longer strings are split into strings no longer than the maximum length. NEWLINE_CONSUME allows newlines to be included in strings instead of terminating them. REGEX specifies a regular expression that a string must match to be returned. Typical usage file(STRINGS myfile.txt myfile) stores a list in the variable "myfile" in which each item is a line from the input file. GLOB will generate a list of all files that match the globbing expressions and store it into the variable. Globbing expressions are similar to regular expressions, but much simpler. If RELATIVE flag is specified for an expression, the results will be returned as a relative path to the given path. (We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.) Examples of globbing expressions include: *.cxx - match all files with extension cxx *.vt? - match all files with extension vta,...,vtz f[3-5].txt - match files f3.txt, f4.txt, f5.txt GLOB_RECURSE will generate a list similar to the regular GLOB, except it will traverse all the subdirectories of the matched directory and match the files. Subdirectories that are symlinks are only traversed if FOLLOW_SYMLINKS is given or cmake policy CMP0009 is not set to NEW. See cmake --help-policy CMP0009 for more information. Examples of recursive globbing include: /dir/*.py - match all python files in /dir and subdirectories MAKE_DIRECTORY will create the given directories, also if their parent directories don't exist yet RENAME moves a file or directory within a filesystem, replacing the destination atomically. REMOVE will remove the given files, also in subdirectories REMOVE_RECURSE will remove the given files and directories, also non-empty directories RELATIVE_PATH will determine relative path from directory to the given file. TO_CMAKE_PATH will convert path into a cmake style path with unix /. The input can be a single path or a system path like "$ENV{PATH}". Note the double quotes around the ENV call TO_CMAKE_PATH only takes one argument. This command will also convert the native list delimiters for a list of paths like the PATH environment variable. TO_NATIVE_PATH works just like TO_CMAKE_PATH, but will convert from a cmake style path into the native path style \ for windows and / for UNIX. DOWNLOAD will download the given URL to the given file. If LOG var is specified a log of the download will be put in var. If STATUS var is specified the status of the operation will be put in var. The status is returned in a list of length 2. The first element is the numeric return value for the operation, and the second element is a string value for the error. A 0 numeric error means no error in the operation. If TIMEOUT time is specified, the operation will timeout after time seconds, time should be specified as an integer. The INACTIVITY_TIMEOUT specifies an integer number of seconds of inactivity after which the operation should terminate. If EXPECTED_MD5 sum is specified, the operation will verify that the downloaded file's actual md5 sum matches the expected value. If it does not match, the operation fails with an error. If SHOW_PROGRESS is specified, progress information will be printed as status messages until the operation is complete. UPLOAD will upload the given file to the given URL. If LOG var is specified a log of the upload will be put in var. If STATUS var is specified the status of the operation will be put in var. The status is returned in a list of length 2. The first element is the numeric return value for the operation, and the second element is a string value for the error. A 0 numeric error means no error in the operation. If TIMEOUT time is specified, the operation will timeout after time seconds, time should be specified as an integer. The INACTIVITY_TIMEOUT specifies an integer number of seconds of inactivity after which the operation should terminate. If SHOW_PROGRESS is specified, progress information will be printed as status messages until the operation is complete. The file() command also provides COPY and INSTALL signatures: file( files... DESTINATION [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS] [FILES_MATCHING] [[PATTERN | REGEX ] [EXCLUDE] [PERMISSIONS permissions...]] [...]) The COPY signature copies files, directories, and symlinks to a destination folder. Relative input paths are evaluated with respect to the current source directory, and a relative destination is evaluated with respect to the current build directory. Copying preserves input file timestamps, and optimizes out a file if it exists at the destination with the same timestamp. Copying preserves input permissions unless explicit permissions or NO_SOURCE_PERMISSIONS are given (default is USE_SOURCE_PERMISSIONS). See the install(DIRECTORY) command for documentation of permissions, PATTERN, REGEX, and EXCLUDE options. The INSTALL signature differs slightly from COPY: it prints status messages, and NO_SOURCE_PERMISSIONS is default. Installation scripts generated by the install() command use this signature (with some undocumented options for internal use). EOF return $txt } sub get_IF_info() { my $txt = <) True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number. False if the constant is 0, OFF, NO, FALSE, N, IGNORE, "", or ends in the suffix '-NOTFOUND'. Named boolean constants are case-insensitive. If the argument is not one of these constants, it is treated as a variable: if() True if the variable is defined to a value that is not a false constant. False otherwise. if(NOT ) True if the expression is not true. if( AND ) True if both expressions would be considered true individually. if( OR ) True if either expression would be considered true individually. if(COMMAND command-name) True if the given name is a command, macro or function that can be invoked. if(POLICY policy-id) True if the given name is an existing policy (of the form CMP). if(TARGET target-name) True if the given name is an existing target, built or imported. if(EXISTS file-name) if(EXISTS directory-name) True if the named file or directory exists. Behavior is well-defined only for full paths. if(file1 IS_NEWER_THAN file2) True if file1 is newer than file2 or if one of the two files doesn't exist. Behavior is well-defined only for full paths. if(IS_DIRECTORY directory-name) True if the given name is a directory. Behavior is well-defined only for full paths. if(IS_SYMLINK file-name) True if the given name is a symbolic link. Behavior is well-defined only for full paths. if(IS_ABSOLUTE path) True if the given path is an absolute path. if( MATCHES regex) True if the given string or variable's value matches the given regular expression. if( LESS ) if( GREATER ) if( EQUAL ) True if the given string or variable's value is a valid number and the inequality or equality is true. if( STRLESS ) if( STRGREATER ) if( STREQUAL ) True if the given string or variable's value is lexicographically less (or greater, or equal) than the string or variable on the right. if( VERSION_LESS ) if( VERSION_EQUAL ) if( VERSION_GREATER ) Component-wise integer version number comparison (version format is major[.minor[.patch[.tweak]]]). if(DEFINED ) True if the given variable is defined. It does not matter if the variable is true or false just if it has been set. if((expression) AND (expression OR (expression))) The expressions inside the parenthesis are evaluated first and then the remaining expression is evaluated as in the previous examples. Where there are nested parenthesis the innermost are evaluated as part of evaluating the expression that contains them. The if command was written very early in CMake's history, predating the \${} variable evaluation syntax, and for convenience evaluates variables named by its arguments as shown in the above signatures. Note that normal variable evaluation with \${} applies before the if command even receives the arguments. Therefore code like set(var1 OFF) set(var2 "var1") if(\${var2}) appears to the if command as if(var1) and is evaluated according to the if() case documented above. The result is OFF which is false. However, if we remove the \${} from the example then the command sees if(var2) which is true because var2 is defined to "var1" which is not a false constant. Automatic evaluation applies in the other cases whenever the above-documented signature accepts : 1) The left hand argument to MATCHES is first checked to see if it is a defined variable, if so the variable's value is used, otherwise the original value is used. 2) If the left hand argument to MATCHES is missing it returns false without error 3) Both left and right hand arguments to LESS GREATER EQUAL are independently tested to see if they are defined variables, if so their defined values are used otherwise the original value is used. 4) Both left and right hand arguments to STRLESS STREQUAL STRGREATER are independently tested to see if they are defined variables, if so their defined values are used otherwise the original value is used. 5) Both left and right hand argumemnts to VERSION_LESS VERSION_EQUAL VERSION_GREATER are independently tested to see if they are defined variables, if so their defined values are used otherwise the original value is used. 6) The right hand argument to NOT is tested to see if it is a boolean constant, if so the value is used, otherwise it is assumed to be a variable and it is dereferenced. 7) The left and right hand arguments to AND OR are independently tested to see if they are boolean constants, if so they are used as such, otherwise they are assumed to be variables and are dereferenced. EOF return $txt; } 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(" --bin (-b) = Show binary items and sources.\n"); prt(" --load (-l) = Set to load log at end.\n"); prt(" --List (-L) = Show 'LIST' sets.\n"); prt(" --install (-i) = Show 'INSTALL' actions.\n"); ###prt(" --IF (-I) = Show 'IF' tags.\n"); prt(" --options (-o) = Show 'OPTION' list.\n"); prt(" --set (-s) = Show 'SET' lists.\n"); prt(" --verb[n] (-v) = Bump [or set] verbosity. def=$verbosity\n"); } # eof - chkcmake.pl