#!/usr/bin/perl -w # NAME: vcproj05.pl # AIM: To scan a VCPROJ file, and show the results, and write (temp) DSP/DSW files. # Since this is all about MSVC things, no attempt has been made to run it in unix. # 2019-09-27 - Try to remove a persistent wanring on VCProjectUpgraderObjectName # 2016-11-23 - Attempt some fixes for MSVC14 # 19/06/2016 - -v should list SOURCES found # 24/04/2015 - Add escape_regex() service to escape a string # 05/04/2015 - Further fixes when processiog # 21/05/2013 - Small fix - was putting SRCS twice add_library( # 17/05/2013 - Add -o option to set output directory of CMakeLists.txt # 29/07/2012 - Another try at doing a cmake output - getting messy # 19/06/2012 - Added 4996;4013;4018;4024;4047;4244 # 10/04/2012 - Extend to MSVC10 *.vcxproj files - looking good 14/04/2012 # 19/01/2012 - Output the 'temp' DSP written # 04/11/2011 - Warn about wild card inputs... # 28/10/2011 - Fix like tempcopydsp.bat to COPY the DSW # 21/10/2011 - Add an input repsponse file - $in_input_file,... # 18/10/2011 - Reduce output if NOT verbose! # 13/07/2011 - If a DSP destination directory given, try to FIX all DSP file source relative to this directory # 01/12/2010 - Some updates for VC90 # 24/11/2010 - Add in VC10 support - # 04/08/2010 - More special fixes for various things... # 2010/07/30 - Special fix of Simgear.cs to SimGear-cs to suit my system... see $dbg_sl_14 # 2010/05/31 - For FLTK project, include *.fl in 'C' sources # 2010/05/01 - Fixed -dsp=. (ie a relative input) to absolute using like $sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of output # 2010/04/23 - Add -ll to load log, and -fix-rel, to FIX the relative source and /I to the dsp output directory # 2010/04/18 - Remove WARNING: DOES NOT CONTAIN(12) 'Filter'?, and use a default filter # 2010/03/08 - Remove write tempvcx.xml from scanvc.pl, or only to perl base directory... # 2010/03/01 - if vcproj contains IgnoreDefaultLibraryNames="MSVCRT", add /nodefaultlib:"MSVCRT" to DSP # Add this to the -NEW_OUT- substitution parameter - that is to the # ADD LINK32 line. # Can be DIFFERENT per configuration. Altered scanvc.pl to collect this, and fgdsphdrs03.pl to do substitution # 2010/01/16 - Feeling confident of scans and dsp written - add write actual replacement! # BUT first, begin to use File::Spec... # 2009/11/11 - Final tidying up - seems to work fine... # 2009/10/20 - support MULTIPLE configurations - not compatible with previous versions # which alwasy had only 2 configurations - Debug and Release. # 20090912 - add display of CWD, if can not find INPUT file name... # This uses the services in scanvc.pl, to standardise the processing of a VCPROJ file # so this is very different to vcproj03.pl, which had its own services to do the scan. # 2009/09/22 - separarate into multiple 'temp' DSP outputs, using -NEW_PROJECT_NAME- # but also avoid overwrtting previous out of same name... # 2010/01/14 - add a DSP COMPARE, if one already exist, and if requested... # 2009-06-05 also try to attempt to output what the project will create... exe,lib,dll,... # 05/12/2008 geoff mclane http://geoffair.net/mperl use strict; use warnings; use Cwd; use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] ) use File::Spec; # File::Spec->rel2abs($rel); # we are IN the SLN directory, get ABSOLUTE from RELATIVE unshift(@INC, 'C:/GTools/perl'); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl'! Check location and \@INC content.\n"; require 'lib_dsphdrs.pl' or die "Unable to load 'lib_dsphdrs.pl'! Check location and \@INC content.\n"; require 'lib_vcscan.pl' or die "Unable to load 'lib_vcscan.pl'! Check location and \@INC content.\n"; require 'lib_params.pl' or die "Unable to load 'lib_params.pl'! Check location and \@INC content.\n"; require 'lib_cmake.pl' or die "Unable to load 'lib_cmake.pl'! Check location and \@INC content.\n"; # log file stuff our ($LF); my $perl_base = "C:\\GTools\\perl"; # perl directory my $PATH_SEP = "\\"; my $temp_dir = $perl_base; my $pgmname = $0; if ($pgmname =~ /\w{1}:\\.*/) { my @tmpsp = split(/\\/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $perl_base."\\temp.$pgmname.txt"; open_log($outfile); my $vers = "2016-11-23"; # some fixes for MSVC14 2015 #my $vers = "2016-06-19"; # -v to list the sources #my $vers = "2015-04-24"; # removed some warnings mainly #my $vers = "2014-01-03"; # removed some warnings mainly #my $vers = "2012-07-19"; # more work on loading 1 vcproj file #my $vers = "2012-06-19"; # try to include vcxproj files #my $vers = "2012-04-10"; # try to include vcxproj files #my $vers = "2011-11-04"; # minor fix #my $vers = "2011-10-28"; # some fixes # $vers = "2011-10-18"; # much reduced output with 'verbosity' # $vers = "2011-07-13"; # features my $sort_by_type = 1; my $sort_by_name = 1; my $load_log = 0; # load LOG file at end my $write_dsp = 0; my $use_lib_option_var = 1; my $combine_lib_source = 1; my $add_3rdparty_stuff = 0; # add the MSVC 3rdparty blob my $out_dsp_dir = $perl_base; # this can be changed by -dsp= my $g_had_dsp = 0; # if given an OUTPUT DSP directory # my $dbg_val = 4+2; # 1=split defines, 2=no show defines, etc, 4=show sources; my $dbg_val = 0; # 1=split defines, 2=no show defines, etc, 4=show sources; #my $dbg4write = -1; # everything ON my $dbg4write = 0; # nothing ON #my $dbg4write = 1; # minimal ON #my $dbg4write = 2; # show source files ON my $comp_2_dsps = 0; my $out_bat_file = $perl_base."\\tempcopydsp.bat"; my $fix_rel_paths = 0; # if given an output dsp directory, fix the releative source paths my $debug_dsw_write = 0; # write DSW debug silently #my $debug_dsw_write = -1; # add write DSW debug info my $verbosity = 0; my $proj_name = ''; sub get_write_dsp_files() { return $write_dsp; } sub get_pgmname() { return $pgmname; } sub get_PATH_SEP() { return $PATH_SEP; } sub get_dsp_out_dir() { return $out_dsp_dir; } my @system_libs = qw(kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib ws2_32.lib); sub is_system_lib($) { my $lib = shift; my $lclib = lc($lib); my ($tst); foreach $tst (@system_libs) { return 1 if ($lclib eq $tst); } return 0; } sub VERB1() { return ($verbosity >= 1); } sub VERB2() { return ($verbosity >= 2); } sub VERB5() { return ($verbosity >= 5); } sub VERB9() { return ($verbosity >= 9); } # program variables my $in_file = ''; my $sln_path = ''; my $active_project = ''; # active project during chk_relative_paths my $in_input_file = 0; my @user_inputs = (); my $act_config = 0; # 0=Release 1=Debug my $commdir = ''; my @proj_hash_array = (); # for each vcproj file processed, push the project $rh here my %shown_warn = (); # 20/06/2012 - output a cmake file ######################################## ### SHARED RESOURCES, VALUES ### ======================== our $fix_relative_sources = 1; our %g_user_subs = (); # supplied by USER INPUT our %g_user_condits = (); # conditionals supplied by the user # Auto output does the following - # For libaries # Debug: '/out:"lib\barD.lib"' # Release:'/out:"lib\barD.lib"' # for programs # Debug: '/out:"bin\fooD.exe"' # Release:'/out:"bin\foo.exe"' # This also 'adds' missing 'include' files #Bit: 1: Use 'Debug\$proj_name', and 'Release\$proj_name' for intermediate and out directories #Bit: 2: Set output to lib, or bin, and names to fooD.lib/foo.lib or barD.exe/bar.exe #Bit: 4: Set program dependence per library output directories #Bit: 8: Add 'msvc' to input file directory, if no target directory given #Bit: 16: Add program library dependencies, if any, to DSW file output. #Bit: 32: Add all necessary headers to the DSP file. That is scan the sources for #include "foo.h", etc. #Bit: 64: Write a blank header group even there are no header files for that component. #Bit: 128: Add defined item of HAVE_CONFIG_H to all DSP files. #Bit: 256: Exclude projects in SUBDIRS protected by a DEFINITION macro, else include ALL. #Bit: 512: Unconditionally add ANY libraries build, and NOT excluded to the last application #Bit:1024: If NO users conditional, do sustitution, if at all possible, regardless of TRUE or FALSE #Bit:2048: Add User -L dependent libraries to each application #Bit: These can be given as an integer, or the form 2+8, etc. Note using -1 sets ALL bits on. #Bit: Bit 32 really slows down the DSP creation, since it involves scanning every line of the sources. my $auto_max_bit = 512; our $auto_on_flag = -1; #Bit: ALL ON by default = ${$rparams}{'CURR_AUTO_ON_FLAG'} sub get_curr_auto_flag() { return $auto_on_flag; } #my ($g_in_name, $g_in_dir); #my ($root_file, $root_folder); #sub get_root_dir() { return $root_folder; } our $exit_value = 0; # But SOME Makefile.am will use specific 'paths' so the above can FAIL to find # a file, so the following two 'try harder' options, will do a full 'root' # directory SCAN, and search for the file of that name in the scanned files our $try_harder = 0; our $try_much_harder = 0; # ============================================================================== our $process_subdir = 0; our $warn_on_plus = 0; # ============================================================================== # NOTE: Usually a Makefile.am contains SOURCE file names 'relative' to itself, # which is usually without any path. This options ADDS the path to the # Makefile.am, and then substracts the 'root' path, to get a SOURCE file # relative to the 'root' configure.ac, which is what is needed if the DSP # is to be placed in a $target_dir, and we want the file relative to that our $add_rel_sources = 1; our $target_dir = ''; # ============================================================================== our $ignore_EXTRA_DIST = 0; our $added_in_init = ''; our $supp_make_in = 0; # Support Makefile.in scanning our $project_name = ''; # a name to override any ac scanned name of the project ###my $dsp_files_skipped = 0; ### ============================= # offsets into REF_LIB_LIST array our $RLO_MSG = 0; our $RLO_PRJ = 1; our $RLO_VAL = 2; our $RLO_NAM = 3; our $RLO_EXC = 4; ### ============================= my $out_cmake_dir = ''; my $write_cmake = 0; my ($rparams); # the one and only, init per first file input my $got_par = 0; # my $rex = ${$rparams}{'AM_EXCLUDED_DIRS'}; # get stored EXCLUDED directory HASH (if any!) # my $proj_root = ${$rparams}{'ROOT_FOLDER'}; # my $proj_title = ${$rparams}{'PROJECT_NAME_MASTER'}; # my $rprojsh = ${$rparams}{'REF_PROJECTS_HASH'}; # my $rlib_lists = ${$rparams}{'REF_LIB_LISTS'}; # make list of LIBRARIES written # optional - my $rxj = ${$rparams}{'REF_JOINED_EXCLUDED'}; my $inst_hdr_path = 'include'; my $inst_lib_path = 'lib'; my $inst_bin_path = 'bin'; sub get_inst_hdr_path() { return $inst_hdr_path; } sub get_inst_lib_path() { return $inst_lib_path; } sub get_inst_hdr_bin() { return $inst_bin_path; } sub get_write_cmake_files() { return $write_cmake; } my %by_proj_includes = (); my %by_proj_defines = (); my %by_proj_defused = (); my $proj_incs = ''; # like '/I "."' for -NEW_INCS- GLOBAL my $proj_defs = ''; # like '/D "_CRT_SECURE_NO_WARNINGS"'; sub get_project_incs($) { my $proj = shift; my $pi = ''; $pi = $by_proj_includes{$proj} if (defined $by_proj_includes{$proj}); return $pi; } sub get_project_defs($) { my $proj = shift; my $pi = ''; $pi = $by_proj_defines{$proj} if (defined $by_proj_defines{$proj}); $by_proj_defused{$proj} = 1; return $pi; } # FIX20110323 - changed from 'get_user_defs:' to 'get_user_incs:' # should ALSO allow DEFINES (-D) to also be in a BY PROJECT basis # my %by_proj_includes = (); sub get_user_incs($$) { my ($not_used,$proj) = @_; my $pi = get_project_incs($proj); $pi .= ' ' if (length($pi) && length($proj_incs)); $pi .= $proj_incs; prt("[v9] get_user_incs: proj=$proj, return=[$pi]\n") if (VERB9()); return $pi; } sub get_user_defs($$) { my ($not_used,$proj) = @_; my $pd = get_project_defs($proj); $pd .= ' ' if (length($pd) && length($proj_defs)); $pd .= $proj_defs; prt("[v9] get_user_defs: proj=$proj, return=[$pd]\n") if (VERB9()); return $pd; } # ### DEBUG ## my $dbg_01 = 0; # show commands my $dbg_02 = 0; # show EACH tag my $dbg_03 = 0; # tag stack debug - show open and close my $dbg_04 = 0; # if $dbg_02, also show complete 'from' item my $dbg_05 = 0; # show each configuration PUSHED my $dbg_06 = 0; # show additional debug for get_rt_value/set_curr_config my $dbg_07 = 0; # show ' Property: '... my $dbg_08 = 0; # show ' ItemDef: '... my $dbg_09 = 0; # show full tag stack if $dbg_02 my $dbg_10 = 0; # setting a unsetting of $incommand if (-d "C:\\MDOS") { $out_bat_file = "C:\\MDOS\\tempcopydsp.bat"; } my $adj_inter = 0; # Adjust output and inter directories to "Release\\" and "Debug\\" my $adj_out = 0; # Adjust output to "bin\\.exe" and "bin\\D.exe" for EXE and DLL # projects, and "lib\\.lib" and "lib\\D.lib" for libraries. my $adj_rt = ''; # Adjust runtime, D = /MD and /MDd, T = /MT and /MTd, accordingly. my $del_ndl_all = 0; my $del_dll_all = 0; # remove any DLL build if both DLL and static, or change to static if only DLL my $del_spl_bld = 0; # remove any Special Tool Build blocks from DSP my $debug_on = 0; # 0 for release, but on to load default input (when using the editor say) my $def_in_file = 'C:\Projects\notepad-plus\PowerEditor\visual.net\notepadPlus.vcproj'; my $def_out_dsp_dir = 'C:\Projects\notepad-plus'; ###my $def_in_file = 'C:\GTools\ConApps\test_simp\build\test_simp.sln'; ###my $def_out_dsp_dir = 'C:\GTools\ConApps\test_simp\build'; #my $def_in_file = 'C:\Projects\lpng159\build\libpng.sln'; #my $def_in_file = 'C:\Projects\lpng159\build\INSTALL.vcxproj'; #my $def_in_file = 'C:\Projects\lpng159\build\ALL_BUILD.vcxproj'; #my $def_out_dsp_dir = 'C:\Projects\lpng159\build'; #my $def_in_file = 'C:\Projects\lpng159\temp-static\png15_static.vcxproj'; #my $def_out_dsp_dir = 'C:\Projects\lpng159\temp-static'; #my $def_in_file = 'C:\Projects\lpng159\temp-shared\png15.vcxproj'; #my $def_out_dsp_dir = 'C:\Projects\lpng159\temp-shared'; #my $def_in_file = 'C:\Projects\zlib-1.2.6\temp\zlib.vcxproj'; #my $def_out_dsp_dir = 'C:\Projects\zlib-1.2.6\temp'; #my $def_in_file = 'C:\FG\10\flightgear\build\src\FDM\YASim\yasim-proptest.vcxproj'; #my $def_out_dsp_dir = 'C:\FG\10\flightgear\build'; #my $def_in_file = 'C:\Projects\curl-7.20.1\lib\libcurl.vcproj'; #my $def_out_dsp_dir = 'C:\Projects\curl-7.20.1\packages\Win32\msvc'; my @warnings = (); #-- get current directory my $pwd = cwd(); my @dsp_file_list = (); # simple list my @project_list = (); # [0]=name [1]=file my $sln_root_dir = ''; # if given a SOLUTION FILE # debug my $dbg_sl_01 = 0; my $dbg_sl_02 = 0; my $dbg_sl_03 = 0; my $dbg_sl_04 = 0; # show_hash_results3($rh) if ($dbg_sl_04); my $dbg_sl_05 = 0; # prt( "[dbg_s105] $pgmname: Scanning [$in]...\n" ) if ($dbg_sl_05); my $dbg_sl_06 = 0; # show parse_arg in detail my $dbg_sl_07 = 0; # prt("[dbg_sl_07] Check relative vcd=[$vcd], out=[$outd]\n") if ($dbg_sl_07); my $dbg_sl_08 = 0; # chk_relative_paths: show each config item my $dbg_sl_09 = 0; # chk_relative_paths: show each source item, and any CHANGE my $dbg_sl_10 = 0; # chk_relative_paths: show each other config item, and any CHANGE my $dbg_sl_11 = 0; # chk_relative_paths: show any POST changes -NEW_POST- my $dbg_sl_12 = 0; # debug sub get_new_post_string($$$$$) { # $v2,\$ok,$rp,$vcd,$outd); my $dbg_sl_13 = 0; my $dbg_sl_14 = 0; my $dbg_sl_15 = 0; # prt( "Stored \$sln_projpath{$projname} = [0:$projfile,1:$projff,2:$relpath,3:$dspfile,4:$fdspfil]\n"); my $dbg_sl_16 = 0; # show each project, and its ID, as found sub get_sl_debug_stg() { my $stg = ''; if ($dbg_sl_01) { $stg .= "01 "; }; if ($dbg_sl_02) { $stg .= "02 "; }; if ($dbg_sl_03) { $stg .= "03 "; }; if ($dbg_sl_04) { $stg .= "04 "; }; if ($dbg_sl_05) { $stg .= "05 "; }; if ($dbg_sl_06) { $stg .= "06 "; }; if ($dbg_sl_07) { $stg .= "07 "; }; if ($dbg_sl_08) { $stg .= "08 "; }; if ($dbg_sl_09) { $stg .= "09 "; }; if ($dbg_sl_10) { $stg .= "10 "; }; if ($dbg_sl_11) { $stg .= "11 "; }; if ($dbg_sl_12) { $stg .= "12 "; }; if ($dbg_sl_13) { $stg .= "13 "; }; if ($dbg_sl_14) { $stg .= "14 "; }; $stg .= "dbg4Write=$dbg4write " if ($dbg4write); $stg .= "debug_dsw_write=$debug_dsw_write " if ($debug_dsw_write); return $stg; } sub set_sl_debug_val($) { my ($v) = shift; $dbg_sl_01 = $v; $dbg_sl_02 = $v; $dbg_sl_03 = $v; $dbg_sl_04 = $v; $dbg_sl_05 = $v; $dbg_sl_06 = $v; $dbg_sl_07 = $v; $dbg_sl_08 = $v; $dbg_sl_09 = $v; $dbg_sl_10 = $v; $dbg_sl_11 = $v; $dbg_sl_12 = $v; $dbg_sl_13 = $v; $dbg_sl_14 = $v; } sub set_sl_debug_on() { set_sl_debug_val(1); $load_log = 1; } sub set_sl_debug_off() { set_sl_debug_val(0); } my $curr_app_type = ''; # APP_TYPE # $app_console_stg = 'Console Application' = get_dsp_head_console # $app_windows_stg = 'Application' = get_dsp_head_app # $app_dynalib_stg = 'Dynamic-Link Library' = get_dsp_head_dynalib # $app_statlib_stg = 'Static Library' = get_dsp_head_slib sub prtw($) { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } sub show_warnings() { if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS ...\n" ); foreach my $line (@warnings) { prt("$line\n" ); } prt("\n"); } else { prt("\nNo warnings issued.\n\n") if (VERB5()); } } sub pgm_exit($$) { my ($val,$msg) = @_; show_warnings(); #my $dbs = fgs_get_dbg_stg(); my $dbs = svc_get_dbg_stg(); if (length($dbs)) { prt("WARNING: Debug is ON for [$dbs], in fgscanvc03.pl\n" ); } $dbs = get_sl_debug_stg(); if (length($dbs)) { prt("WARNING: Debug is ON for [$dbs], in $pgmname\n" ); } else { prt("Appears no DEBUG item remain on...\n") if (VERB5()); } if (length($msg)) { $msg .= "\n" if ( !($msg =~ /\n$/) ); prt($msg); } close_log($outfile,$load_log); # unlink($outfile); # delete output file exit($val); } sub is_c_source_ext($) { my ($fil) = shift; my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ ); my $lce = lc($ext); return 1 if (($lce eq '.c') || ($lce eq '.cxx') || ($lce eq '.cpp') || ($lce eq '.cc')); return 1 if ($lce eq '.fl'); # 2010-05-31 - added for FLTK projects return 0; } sub is_sln_ext($) { my ($fil) = shift; my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ ); my $lce = lc($ext); if ($lce eq '.sln') { return 1; } return 0; } sub is_vcproj_ext($) { my ($fil) = shift; my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ ); my $lce = lc($ext); return 1 if ($lce eq '.vcproj'); return 0; } sub is_vcxproj_ext($) { my $fil = shift; my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ ); my $lce = lc($ext); return 1 if ($lce eq '.vcxproj'); # 24/11/2010 VC10 support return 0; } # escape ^ $ . | { } [ ] ( ) * + ? \ sub escape_regex($) { my $txt = shift; my $ntxt = ''; my $len = length($txt); my ($i,$ch); for ($i = 0; $i < $len; $i++) { $ch = substr($txt,$i,1); if (($ch eq '^')||($ch eq '$')||($ch eq '.')||($ch eq '|')||($ch eq '{')||($ch eq '}')) { $ntxt .= '\\'; } elsif (($ch eq '\\')||($ch eq '/')||($ch eq '(')||($ch eq ')')||($ch eq '[')||($ch eq ']')) { $ntxt .= '\\'; } elsif (($ch eq '*')||($ch eq '+')||($ch eq '?')) { $ntxt .= '\\'; } $ntxt .= $ch; } return $ntxt; } # =================================================================== # -NEW_INCS- = [/I "." /I "..\include"], and # -NEW_DEFS- = [/D "NDEBUG"... ] # Maybe could - # (a) ensure a certain /I "somepath", exists, adding it if NOT # (b) adjust certain /I "..\path.x64" to a different /I "..\new\path" # (c) delete duplicates # (d) etc # =================================================================== # reduce the noise... my $prev_inc_warn = ''; my $prev_def_warn = ''; my $prev_inc_added = ''; my $prev_def_added = ''; my $prev_sdk_added = ''; my $prev_alut_added = ''; my $prev_item_dump1 = ''; my $prev_item_dump2 = ''; sub get_new_inc_hash($$$$$$) { my ($v,$rok,$rp,$vcd,$outd,$ky) = @_; my $len = length($v); my %hash = (); my %dupes = (); my ($i,$ch,$nc,$tag,$val,$pc,$ra,$nval,$i2,$qt); my ($fp,$np,$had_al,$inc_tag,$had_crt,$def_tag,$had_alu,$had_dot,$had_cfg); # process the line, char by char... $had_al = 0; $had_alu = 0; $inc_tag = ''; $had_crt = 0; $def_tag = ''; $had_dot = 0; $had_cfg = 0; $ch = ''; for ($i = 0; $i < $len; $i++) { $i2 = $i + 1; $pc = $ch; # keep PREVIOUS char $ch = substr($v,$i,1); $nc = ($i2 < $len) ? substr($v,$i2,1) : ''; if ( (($ch eq '/')||($ch eq '-')) && (length($nc)) ) { $tag = $ch; # begin a SWITCH item $i++; # bump to NEXT char for (; $i < $len; $i++) { $pc = $ch; # keep PREVIOUS char $ch = substr($v,$i,1); $nc = ($i2 < $len) ? substr($v,$i2,1) : ''; last if ($ch eq '"'); # found first QUOTE last if ($ch =~ /\s/); # or found a SPACE $tag .= $ch; } if ($ch =~ /\s/) { # if a SPACE, get to NEXT sig char $i++; for (; $i < $len; $i++) { $pc = $ch; # keep PREVIOUS char $ch = substr($v,$i,1); last if ($ch eq '"'); last if ( !($ch =~ /\s/) ); } } $qt = ''; # assume NO 'quote' $val = $ch; # start of a VALUE $i2 = $i + 1; if ($i2 < $len) { if ( $ch eq '"' ) { $i++; # ok, do have QUOTED text $qt = $ch; # keep 'quote' $pc = $ch; # keep PREVIOUS char $ch = substr($v,$i,1); # and get NEXT char $val .= $ch; # add to collected value } } else { ${$rok} = 0; prtw("WARNING:1:$active_project: Ran out of char! With [$v] FAILED!\n"); return \%hash; } $i++; if (length($qt)) { # process until next 'quote' found, 2010-08-04 but NOT escaped with '\' for (; $i < $len; $i++) { $pc = $ch; # keep PREVIOUS char $ch = substr($v,$i,1); $val .= $ch; last if ( ($ch eq $qt) && ($pc ne "\\") ); } } else { # or process until a space found for (; $i < $len; $i++) { $pc = $ch; # keep PREVIOUS char $ch = substr($v,$i,1); last if ($ch =~ /\s/); $val .= $ch; } } # we have (/|-)$tag ["]$val["] # ============================ $nval = strip_quotes($val); if ($nval eq '.') { # this stays as is $had_dot = 1; } elsif ($tag =~ /^(-|\/)I$/) { # its a /I "path" type - need new relative item? prtw("WARNING:$active_project: Multiple I tags. Got [$inc_tag], NOW [$tag]! CHECK THIS\n") if (length($inc_tag) && ($tag ne $inc_tag)); $inc_tag = $tag; $fp = $vcd; # ==================================================================== $had_al = 1 if ($nval =~ /OpenAL/i); # if got an OpenAL (AL/al.h) include $had_alu = 1 if ($nval =~ /alut/); $nval =~ s/SimGear\.cs/simgear-cs/i; # SPECIAL FIX Fred vs Geoff $nval =~ s/3rdParty\.x64/3rdParty/i; # SPECIAL FIX Fred vs Geoff $nval =~ s/install(\\|\/)msvc90(\\|\/)OpenSceneGraph/OpenSceneGraph/i; # SPECIAL FIX Fred vs Geoff $nval =~ s/install(\\|\/)msvc90-64(\\|\/)OpenSceneGraph/OpenSceneGraph/i; # SPECIAL FIX Fred vs Geoff $nval =~ s/install(\\|\/)msvc71(\\|\/)OpenSceneGraph/OpenSceneGraph/i; # SPECIAL FIX Fred vs Geoff # ==================================================================== $fp .= "\\" if ( !( ($fp =~ /(\\|\/)$/) || ($nval =~ /^(\\|\/)/) ) ); $fp .= $nval; # get the FULL (relative) path $fp = fix_rel_path3($fp,'get_new_inc_hash'); $np = get_rel_dos_path($fp,$outd); $np =~ s/(\\|\/)$//; $val = add_quotes($np); } elsif ($tag =~ /^(-|\/)D$/) { prtw("WARNING:$active_project: Multiple D tags. Got [$def_tag], NOW [$tag]! CHECK THIS\n") if (length($def_tag) && ($tag ne $def_tag)); $def_tag = $tag; $had_crt = 1 if ($nval =~ /_CRT_SECURE_NO_WARNINGS/); $had_cfg = 1 if ($nval eq 'HAVE_CONFIG_H'); if ($nval =~ /^DEFAULT_USGS_MAPFILE/) { prt("$active_project: SPECIAL FIX: Dumping tag [$tag $val]\n") if ($prev_item_dump1 ne $active_project); $prev_item_dump1 = $active_project; ${$rok}++; next; } if ($nval =~ /^DEFAULT_PRIORITIES_FILE/) { prt("$active_project: SPECIAL FIX: Dumping tag [$tag $val]\n") if ($prev_item_dump2 ne $active_project); $prev_item_dump2 = $active_project; ${$rok}++; next; } } if (defined $dupes{$val}) { prtw("WARNING:$active_project:SPECIAL FIX: Avoided duplicate [$val]\n"); } else { $hash{$tag} = [] if (!defined $hash{$tag}); $ra = $hash{$tag}; push(@{$ra},$val); # store item in HASH $dupes{$val} = 1; } ${$rok}++; } elsif (($ch eq '/')||($ch eq '-')) { prtw("WARNING:2:$active_project: Ran out of char! With [$v] FAILED!\n"); ${$rok} = 0; return \%hash; } else { if ($ch =~ /\s/) { # forget spaces - just continue } else { prtw("WARNING:3:$active_project: Not A SWITCH! Got [$ch]? With [$v] FAILED!\n"); ${$rok} = 0; return \%hash; } } } # char by char for the whole string # ========================= # Other SPECIAL FIX items # ========================= # -NEW_INCS- if ( (length($inc_tag) > 0) && (defined $hash{$inc_tag}) ) { $ra = $hash{$inc_tag}; if ($active_project =~ /simgear/i) { prt("SPECIAL FIX: for [$active_project]\n"); if ( !$had_al ) { $val = '"C:\Program Files\OpenAL 1.1 SDK\include"'; push(@{$ra},$val); # store item in HASH prt("SPECIAL FIX: Added OpenAL SDK include [$val]\n") if ($active_project ne $prev_sdk_added); $prev_sdk_added = $active_project; ${$rok}++; } if ( !$had_alu) { $val = '"..\..\..\alut\include"'; push(@{$ra},$val); # store item in HASH prt("$active_project:SPECIAL FIX: Added alut include [$val]\n") if ($active_project ne $prev_alut_added); $prev_alut_added = $active_project; ${$rok}++; } } if (!$had_dot) { $val = '"."'; push(@{$ra},$val); # store item in HASH prt("$active_project:SPECIAL FIX: Added [/I $val]\n") if ($active_project ne $prev_inc_added); $prev_inc_added = $active_project; ${$rok}++; } } elsif ($ky eq '-NEW_INCS-') { prtw("WARNING:$active_project: Potential SPECIAL FIXES missed for $ky! No /I tag in [$v]???\n") if ($active_project ne $prev_inc_warn); $prev_inc_warn = $active_project; } # -NEW_DEFS- if ( (length($def_tag) > 0) && (defined $hash{$def_tag}) ) { $ra = $hash{$def_tag}; if ( ! $had_crt ) { $val = '"_CRT_SECURE_NO_WARNINGS"'; push(@{$ra},$val); # store item in HASH prt("$active_project:SPECIAL FIX: Added CRT [$val]\n"); ${$rok}++; } if ( ! $had_cfg ) { $val = '"HAVE_CONFIG_H"'; push(@{$ra},$val); # store item in HASH prt("$active_project:SPECIAL FIX: Added CONFIG [$val]\n") if ($prev_def_added ne $active_project); $prev_def_added = $active_project; ${$rok}++; } } elsif ($ky eq '-NEW_DEFS-') { prtw("WARNING:$active_project: Potential SPECIAL FIXES missed for $ky! No /D tag in [$v]???\n") if ($active_project ne $prev_def_warn); $prev_def_warn = $active_project; } return \%hash; # return hash{$tag} = [$val,[$val]] } # could have # -NEW_POST- = [# Begin Special Build Tool #SOURCE="$(InputPath)" #PostBuild_Desc= #PostBuild_Cmds=if not exist ..\..\..\..\lib md ..\..\..\..\lib copy "$(TargetDir)GLUT32.LIB" ..\..\..\..\lib copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\lib if exist ..\..\..\..\progs\demos copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\progs\demos ## End Special Build Tool # that needs ADJUSTING - wow sub get_new_post_string($$$$$) { # $v2,\$ok,$rp,$vcd,$outd); my ($v,$rok,$rp,$vcd,$outd) = @_; my $len = length($v); my $nv = $v; my $chg = 0; my (@arr,$k,$l1,$itm,$chg1,$chg2,$i,$j,$c,$c2,@a2,@a3,$cmd,$l2,$l3,$np,$rd,$frp); if ($len) { @arr = split("\n",$v); $l1 = scalar @arr; for ($k = 0; $k < $l1; $k++) { $itm = $arr[$k]; if ($itm =~ /^PostBuild_Cmds=(.+)$/) { $cmd = $1; @a2 = split("\t",$cmd); $l2 = scalar @a2; $chg2 = 0; for ($i = 0; $i < $l2; $i++) { $c = $a2[$i]; if ($c =~ /\.\./) { prt("[dbg_sl_12] Needs adjustment [$c]\n") if ($dbg_sl_12); @a3 = split(/\s/,$c); $l3 = scalar @a3; $chg1 = 0; for ($j = 0; $j < $l3; $j++) { $c2 = $a3[$j]; if ($c2 =~ /\.\./) { $rd = $vcd.$c2; $frp = fix_rel_path3($rd,'get_new_post_string'); $np = get_rel_dos_path($frp,$outd); $np =~ s/(\\|\/)$//; prt("REL [$rd]\nnew [$frp]\n") if ($dbg_sl_12); prt(" This one [$c2] to [$np]?\n") if ($dbg_sl_12); if ($np ne $c2) { $a3[$j] = $np; $chg1++; } } } if ($chg1) { $np = ''; foreach $c2 (@a3) { $np .= ' ' if (length($np)); $np .= $c2; } $a2[$i] = $np; $chg2++; } } } if ($chg2) { $rd = ''; foreach $c (@a2) { $rd .= "\t" if (length($rd)); $rd .= $c; } $arr[$k] = $rd; $chg++; prt("old [$cmd]\nnew [$rd]\n") if ($dbg_sl_12); } } } if ($chg) { $nv = ''; foreach $itm (@arr) { $nv .= "\n" if (length($nv)); $nv .= $itm; } if ($v ne $nv) { prt("old [$v]\nnew [$nv]\n") if ($dbg_sl_12); ${$rok} = 1; } } prt("rel=[$rp], vcd=[$vcd], od=[$outd]\n") if ($dbg_sl_12); #pgm_exit(1,"TEMP EXIT"); } return $nv; } # check input libraries to link with # $v = current value # $rok = ref to set if changed # $rp = get_rel_dos_path($vcd,$outd); # changing the PATH # $vcd = directory of the vcproj file # $outd = output directory # can add, substrct, change list # eg # [ul_d.lib sg_d.lib zlibd.lib gdal_id.lib /libpath:"..\..\..\..\plib" /libpath:"..\..\..\..\3rdParty\lib"] # needs to be changed to # [ul_d.lib sg_d.lib zlibd.lib gdal_id.lib /libpath:"..\..\..\plib" /libpath:"..\..\..\3rdParty\lib"] sub get_new_libs_string($$$$$) { # $v2,\$ok,$rp,$vcd,$outd); my ($v,$rok,$rp,$vcd,$outd) = @_; my $len = length($v); my $nv = $v; my $chg = 0; #prt("get_new_libs_string: from [$v]\n"); my @arr = space_split($v); # split on space, but honor inside inverted commas my ($itm,$dir,$fp,$tmp,$rdd,$nitm); my @narr = (); foreach $itm (@arr) { if ($itm =~ /^\/libpath:/) { $dir = strip_quotes(substr($itm,9)); $fp = $vcd; $fp .= "\\" if ( !($fp =~ /(\/|\\)$/) ); $fp .= $dir; $tmp = fix_rel_path3($fp,'get_new_libs_string'); # my $out_dsp_dir = $perl_base; # this can be changed by -dsp= # my $g_had_dsp = 0; # if given an OUTPUT DSP directory $rdd = get_rel_dos_path($tmp,$out_dsp_dir); # changing the PATH $rdd =~ s/\\$//; $nitm = '/libpath:'.add_quotes($rdd); push(@narr,$nitm); #prt("Changed\nfrom [$itm]\nto [$nitm]\n"); ###pgm_exit(1,"CHECK ME"); $chg++; } else { push(@narr,$itm); } } if ($chg) { $nv = ''; foreach $itm (@narr) { $nv .= ' ' if (length($nv)); $nv .= $itm; } ${$rok} = $chg; } return $nv; } sub Get_Default_Group($) { my ($src) = @_; my ($grp,$flt); if (is_c_source_extended($src)) { $grp = get_def_src_grp(); $flt = get_def_src_filt(); } elsif (is_h_source_extended($src)) { $grp = get_def_hdr_grp(); $flt = get_def_hdr_filt(); } elsif (is_resource_file($src)) { $grp = get_def_rcs_grp(); $flt = get_def_rcs_filt(); } else { $grp = "Other Files"; $flt = ''; } return $grp,$flt; } # ====================================================================================== # ok, need to change sources from perhaps '.\src.cxx' to '..\..\lib\src.cxx' - a big job # and LOTS of other things... # ====================================================================================== my $prev_src_fix = ''; sub chk_relative_paths($$$) { my ($rh,$outd,$vcd) = @_; my ($key,$val,$acnt,$i,$src,$grp,$flt,$rp); my ($i2,$rsb,@karr,$scnt,$msg,$ky,$v2,$rih,$ok); my ($k3,$v3,$v,$nv,$tmp,$tmp2); $rp = get_rel_dos_path($vcd,$outd); # changing the PATH ##my $rp2 = get_rel_dos_path($outd,$vcd); # how to get from where we were to now out directory # this would be used to move say 'windows\VC8\mesa\mesa.dsp' to windows\MSVC prt("[dbg_sl_07] Check relative vcd=[$vcd], out=[$outd]\n") if ($dbg_sl_07); prt("chk_relative_paths: [$rp],\n from vcd=[$vcd],\n target =[$outd]\n"); $key = 'PROJECT_NAME'; if (! defined ${$rh}{$key}) { pgm_exit(1,"INTERNAL ERROR: HASH WITHOUT PROJECT_NAME! Can ONLY exit!"); } $active_project = ${$rh}{$key}; my @not_found = (); foreach $key (keys %{$rh}) { $val = ${$rh}{$key}; if ( $key =~ /^CURR_/ ) { # ignore these CURRENT state items } else { if ($key eq 'PROJECT_SRCS') { $acnt = scalar @{$val}; prt("$key - $acnt sources to fix path...\n"); # 'PROJECT_SRCS' for ($i = 0; $i < $acnt; $i++) { $src = ${$val}[$i][0]; $grp = ${$val}[$i][1]; $flt = ${$val}[$i][2]; # SPECIAL FIX - Fred vs Geoff if ($active_project =~ /simgear/i) { ($grp,$flt) = Get_Default_Group($src); ${$val}[$i][1] = $grp; ${$val}[$i][2] = $flt; prt("SPECIAL FIX for [$active_project] [$src] [$grp] [$flt]\n") if ($prev_src_fix ne $active_project); $prev_src_fix = $active_project; } $src =~ s/^\.(\\|\/)//; #$nv = $rp.$src; $tmp = $vcd.$src; $tmp2 = fix_rel_path3($tmp,'chk_relative_paths'); if (-f $tmp2) { $ok = 'ok'; } else { $ok = 'NF'; push(@not_found,$tmp2); } my ($fnm,$fdir) = fileparse($tmp2); $nv = get_rel_dos_path($fdir,$outd); # 2010/05/06 - why ??? $nv =~ s/(\\|\/)$//; $nv .= "\\" if (length($nv) && !($nv =~ /(\\|\/)$/)); $nv .= $fnm; # add back the file name if ($nv eq $src) { prt("Source [$src] not changed. [$grp] [$flt]\n") if ($dbg_sl_09 || VERB1()); } else { prt("Was [$src] GOT CHANGE...\n") if ($dbg_sl_09 || VERB5());; prt("int [$tmp2]\n") if ($dbg_sl_09 || VERB9());; prt("New [$nv] [$grp] [$flt] $ok\n") if ($dbg_sl_09 || VERB1()); ${$val}[$i][0] = $nv; } } } elsif ($key eq 'PROJECT_CFGS') { # my $rcfgs = ${$rh}{'PROJECT_CFGS'}; # 0 1 2 3 # push(@{$rcfgs}, [ $pname, $var1, $conf, $dsp_sub_sub ]); # -NEW_INCS- = [/I "." /I "..\include"] $acnt = scalar @{$val}; prt("$key - $acnt configs...\n"); for ($i = 0; $i < $acnt; $i++) { $i2 = $i + 1; $src = ${$val}[$i][0]; $grp = ${$val}[$i][1]; $flt = ${$val}[$i][2]; $rsb = ${$val}[$i][3]; @karr = keys(%{$rsb}); $scnt = scalar @karr; $msg = sprintf("%3d:",$i2); # prt( "$msg: [$src] [$grp] [$flt] = $scnt\n" ); prt( "$msg: [$src] [$flt] = $scnt config items\n" ); foreach $ky (@karr) { $v2 = ${$rsb}{$ky}; ###prt("Doing [$ky], value [$v2]\n"); $nv = ''; if (($ky eq '-NEW_INCS-')||($ky eq '-NEW_DEFS-')) { # also need to fix things like '/I "..\include"', but NOT '/I "."' $ok = 0; $rih = get_new_inc_hash($v2,\$ok,$rp,$vcd,$outd,$ky); if ($ok) { prt(" = $ky = [") if ($dbg_sl_10); $nv = ''; foreach $k3 (keys %{$rih}) { $v3 = ${$rih}{$k3}; foreach $v (@{$v3}) { $nv .= ' ' if (length($nv)); $nv .= "$k3 $v"; } } if ($nv eq $v2) { prt(" [$nv] NO CHANGE\n") if ($dbg_sl_10); } else { prt("\nnew [$nv], \nwas [$v2]\n") if ($dbg_sl_10); ${$rsb}{$ky} = $nv; #${$val}[$i][3] = $rsb; } } else { prt( " $ky = [$v2] FAILED REF\n" ); } } elsif ($ky eq '-NEW_POST-') { # could have # -NEW_POST- = [# Begin Special Build Tool #SOURCE="$(InputPath)" #PostBuild_Desc= #PostBuild_Cmds=if not exist ..\..\..\..\lib md ..\..\..\..\lib copy "$(TargetDir)GLUT32.LIB" ..\..\..\..\lib copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\lib if exist ..\..\..\..\progs\demos copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\progs\demos ## End Special Build Tool # that needs ADJUSTING - wow $ok = 0; $nv = get_new_post_string($v2,\$ok,$rp,$vcd,$outd); if ($ok) { prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11); ${$rsb}{$ky} = $nv; } else { prt( " $ky = [$v2] NO CHANGES\n" ) if ($dbg_sl_11); } } elsif ($ky eq '-NEW_OUTD-') { $nv = strip_quotes($v2); $nv =~ s/^\.\.\\//; $nv .= "\\" if (!($nv =~ /(\\|\/)$/)); $nv .= $active_project; $nv = add_quotes($nv); prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11); ${$rsb}{$ky} = $nv; } elsif ($ky eq '-NEW_INTER-') { $nv = strip_quotes($v2); $nv =~ s/^\.\.\\//; $nv .= "\\" if (!($nv =~ /(\\|\/)$/)); $nv .= $active_project; $nv = add_quotes($nv); prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11); ${$rsb}{$ky} = $nv; } elsif ($ky eq '-NEW_LIBS-') { $nv = strip_quotes($v2); $ok = 0; $nv = get_new_libs_string($v2,\$ok,$rp,$vcd,$outd); if ($ok) { prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11); ${$rsb}{$ky} = $nv; } else { prt( " $ky = [$v2] NO CHANGES\n" ) if ($dbg_sl_11); } } else { prt( " $ky = [$v2] NOT CHANGED\n" ) if ($dbg_sl_08); } ###prt( "NEXT KEY after $ky [$v2] [$nv]\n"); } } } else { # dealt with 'PROJECT_SRCS' and 'PROJECT_CFGS' above # What about PROJECT_NAME, PROJECT_CCNT, PROJECT_FDIR, PROJECT_FILE # PROJECT_TYPE, PROJECT_DSPF, PROJECT_VERS, PROJECT_APTP, PROJECT_FLAG, PROJECT_MSCV? $tmp = ''; if ($key eq 'PROJECT_NAME') { # $tmp = "Like change name from [$val]?"; } elsif ($key eq 'PROJECT_CCNT') { # $tmp = "Like config count [$val]?"; } elsif ($key eq 'PROJECT_FDIR') { # $tmp = "Like FDIR [$val]?"; } elsif ($key eq 'PROJECT_FILE') { # $tmp = "Like FILE [$val]?"; } elsif ($key eq 'PROJECT_TYPE') { $tmp = "Like TYPE [$val]?"; } elsif ($key eq 'PROJECT_DSPF') { $tmp = "Like DSP FILE [$val]?"; } elsif ($key eq 'PROJECT_VERS') { # $tmp = "Like VERS [$val]?"; } elsif ($key eq 'PROJECT_APTP') { $tmp = "Like APTP [$val]?"; } elsif ($key eq 'PROJECT_FLAG') { # $tmp = "Like FLAG [$val]?"; } elsif ($key eq 'PROJECT_MSCV') { # $tmp = "Like FLAG [$val]?"; } elsif ($key eq 'PROJECT_AM_FILE') { } elsif ($key eq 'PROJECT_ROOT') { } else { $tmp = "Like UNCASED [$val]?"; pgm_exit(1,"CHECKME:chk_relative_paths: key [$key] UNCASED, with val [$val]"); } prt("$key ... any items to change? $tmp\n") if (length($tmp) && $dbg_sl_10); } } } if (@not_found && VERB1()) { $tmp = scalar @not_found; prtw("WARNING: Project $active_project has $tmp MISSING sources!\n"); foreach $src (@not_found) { prt("$src\n"); } } # pgm_exit(1,"Temp stop to check"); } # ensure -NEW_LIBS- hash ref does NOT contain LIBS already in default sub fix_lib_list($) { my ($rh) = @_; my $key = 'PROJECT_CFGS'; my $chgd = 0; my $def = get_def_lib_list(); my @a2 = split(/\s/,$def); if (defined ${$rh}{$key}) { my $val = ${$rh}{$key}; my $k2 = '-NEW_LIBS-'; my $acnt = scalar @{$val}; for (my $i = 0; $i < $acnt; $i++) { my $rsb = ${$val}[$i][3]; # get -NEW_LIBS- hash ref if (defined ${$rsb}{$k2}) { my $v2 = ${$rsb}{$k2}; prt("[dbg_sl_13] [$v2],\nwith default [$def]\n") if ($dbg_sl_13); my @a1 = split(/\s/,$v2); my $chg = 0; my @arr = (); my ($lib, $lib2,$fnd,$lclib); foreach $lib (@a1) { $lclib = lc($lib); if ($lib =~ /^\/libpath:/i) { # no change in these push(@arr,$lib); } else { $fnd = 0; # else check if already in DEFAULTS foreach $lib2 (@a2) { if ($lclib eq lc($lib2)) { $fnd = 1; last; } } if ($fnd) { $chg++; # dump this DUPLICATE } else { push(@arr,$lib); # else keep this } } } if ($chg) { $lib = join(" ",@arr); ${$rsb}{$k2} = $lib; prt(" Set NEW [$lib]\n") if ($dbg_sl_13); $chgd++; } } } # for each configuration if ($chgd) { # pgm_exit(1,"TEMP EXIT"); } } } sub show_project_hash($) { my $rh = shift; my @arr = keys(%{$rh}); my $cnt = scalar @arr; my $rc_files = ${$rh}{'PROJECT_C_SOURCES'}; # = \@c_files; my $rh_files = ${$rh}{'PROJECT_H_SOURCES'}; # = \@h_files; my $ro_files = ${$rh}{'PROJECT_O_SOURCES'}; # = \@o_files; my $name = ${$rh}{'PROJECT_NAME'}; # = $name; my $sdir = ${$rh}{'PROJECT_SDIR'}; # = $sdir; my $type = ${$rh}{'PROJECT_TYPE'}; # = $type; my $rincs = ${$rh}{'PROJECT_INCS'}; # = \%inc_hash; my $rdefs = ${$rh}{'PROJECT_DEFS'}; # = \%def_hash; my $ccnt = scalar @{$rc_files}; my $hcnt = scalar @{$rh_files}; my $ocnt = scalar @{$ro_files}; my $icnt = scalar keys(%{$rincs}); my $dcnt = scalar keys(%{$rdefs}); prt("Project [$name], type [$type], $ccnt C/C++, $hcnt Hdrs, $ocnt Other, $icnt INCS, $dcnt DEFS\n"); my ($key,$val); foreach $key (@arr) { $val = ${$rh}{$key}; if (($key eq 'PROJECT_NAME')||($key eq 'PROJECT_TYPE')||($key eq 'PROJECT_SDIR')) { prt("$key = $val\n"); } elsif (($key eq 'PROJECT_INCS')||($key eq 'PROJECT_DEFS')) { $cnt = scalar keys(%{$val}); prt("$key with $cnt item keys in hash ref\n"); } elsif (($key eq 'PROJECT_C_SOURCES')||($key eq 'PROJECT_H_SOURCES')||($key eq 'PROJECT_O_SOURCES')) { $cnt = scalar @{$val}; prt("$key with $cnt items in ref array\n"); } else { prtw("WARNING: Uncased KEY [$key] FIX ME! 4\n"); } } } sub get_hash_results($$) { my ($nhr,$dsp) = @_; my @arr = keys( %{$nhr} ); my $cnt = scalar @arr; my ($key,$name,$val,$inf,$acnt,$src); my ($grp,$flt,$min1,$min2,$len); my ($i,$i2,$msg,$rsb,$scnt,@karr); my ($ky,$v2,$sdir,$ff,$ok,$type); $key = 'PROJECT_NAME'; $name = ${$nhr}{$key}; $key = 'PROJECT_FDIR'; $sdir = ${$nhr}{$key}; $key = 'PROJECT_APTP'; $type = ${$nhr}{$key}; prt( "Show of NEW hash ref., up to $cnt keys... project [$name]\n" ) if ($dsp); $cnt = 0; my $rpki = get_prj_key_info_ref(); my @c_files = (); my @h_files = (); my @o_files = (); my %inc_hash = (); my %def_hash = (); foreach $key (@arr) { $val = ${$nhr}{$key}; next if ($key =~ /^TEMP_/); if ( $key =~ /^CURR_/ ) { # ignore these CURRENT state items } else { $cnt++; if (defined ${$rpki}{$key}) { $inf = ${$rpki}{$key}; if (($inf =~ /^/)||($inf =~ /^/)) { prt( "$key $inf =[$val]\n" ) if ($dsp); } else { $acnt = scalar @{$val}; prt( "$key $inf =(ARRAY of count $acnt)\n" ) if ($dsp); if ($key eq 'PROJECT_SRCS') { $min1 = 0; $min2 = 0; for ($i = 0; $i < $acnt; $i++) { $src = ${$val}[$i][0]; $grp = ${$val}[$i][1]; $flt = ${$val}[$i][2]; $len = length($src); $min1 = $len if ($len > $min1); $len = length($grp); $min2 = $len if ($len > $min2); } for ($i = 0; $i < $acnt; $i++) { $i2 = $i + 1; $src = ${$val}[$i][0]; $grp = ${$val}[$i][1]; $flt = ${$val}[$i][2]; if ($src =~ /^\w{1}:(\\|\/)/) { # this appears to be a FULL FILE NAME like C: $ff = $src; } else { $ff = fix_rel_path3($sdir.$src,'show_hash_results3'); # in fgutils02.pl } $ok = (-f $ff) ? 'ok' : 'NF'; if (is_c_source_extended($src)) { push(@c_files,$src); } elsif (is_h_source($src)) { push(@h_files,$src); } else { push(@o_files,$src); } # setup for display $src .= ' ' while(length($src) < $min1); $grp .= ' ' while(length($grp) < $min2); $msg = sprintf("%3d:",$i2); prt( "$msg $src $grp $flt $ok\n" ) if ($dsp); } } elsif ($key eq 'PROJECT_CFGS') { # my $rcfgs = ${$rh}{'PROJECT_CFGS'}; # 0 1 2 3 # push(@{$rcfgs}, [ $pname, $var1, $conf, $dsp_sub_sub ]); for ($i = 0; $i < $acnt; $i++) { $i2 = $i + 1; $src = ${$val}[$i][0]; $grp = ${$val}[$i][1]; $flt = ${$val}[$i][2]; $rsb = ${$val}[$i][3]; @karr = keys(%{$rsb}); $scnt = scalar @karr; $msg = sprintf("%3d:",$i2); prt( "$msg $src $grp $flt $scnt\n" ) if ($dsp); foreach $ky (@karr) { $v2 = ${$rsb}{$ky}; prt( " $ky = [$v2]\n" ) if ($dsp); if ($ky eq '-NEW_INCS-') { set_inc_hash(\%inc_hash,$v2); } elsif ($ky eq '-NEW_DEFS-') { set_def_hash(\%def_hash,$v2); } } } } } } else { my $wmsg = "[$key] NOT IN INFO LIST!"; if (!defined $shown_warn{$key}) { prtw( "WARNING:vcpoj05: $wmsg, see sub get_prj_key_info_ref() & \%prj_key_info\n" ); $shown_warn{$key} = 1; } } } } prt("Done show of $cnt keys... project [$name]\n") if ($dsp); my %hash = (); $hash{'PROJECT_C_SOURCES'} = \@c_files; $hash{'PROJECT_H_SOURCES'} = \@h_files; $hash{'PROJECT_O_SOURCES'} = \@o_files; $hash{'PROJECT_NAME'} = $name; $hash{'PROJECT_SDIR'} = $sdir; $hash{'PROJECT_TYPE'} = $type; $hash{'PROJECT_INCS'} = \%inc_hash; $hash{'PROJECT_DEFS'} = \%def_hash; return \%hash; } # dbg_show_entering_files(); # dbg_show_source_files(); # dbg_show_output_files(); # { $dbg_v21 = 1; $dbg_v24 = 1; } # 2009/10/29 - make it work for TWO different forms of VC HASH # 13/07/2011 - if ($out_dsp_dir ne $perl_base), then try to also ADJUST sources sub process_vcproj_file($$) { my ($in, $outd) = @_; my ($key,$pnam,$out,$cnt,$dsp); my ($prjf,$nm,$dir,$ext,$dspf,$tmp2); my ($msg); my ($rdspf,$fprjf,$fdspf,$dprjf,$type); prt( "[dbg_sl_05] $pgmname: Scanning [$in]...\n" ) if ($dbg_sl_05); my ($vc_name,$vc_dir) = fileparse($in); $vc_dir = $pwd."\\" if ($vc_dir =~ /^\.(\\|\/)$/); my $rh = process_VCPROJ3($in); # FIX20120718 - some 'fixes' if NOT already defined if (!defined ${$rh}{'PROJECT_ROOT'}) { ${$rh}{'PROJECT_ROOT'} = $vc_dir; } if (!defined ${$rh}{'PROJECT_AM_FILE'}) { ${$rh}{'PROJECT_AM_FILE'} = $in; } # check for application type over-ride... if (length($curr_app_type)) { $key = 'APP_TYPE'; $key = 'PROJECT_APTP' if (!defined ${$rh}{$key}); if (defined ${$rh}{$key}) { $tmp2 = ${$rh}{$key}; ${$rh}{$key} = $curr_app_type; if ($tmp2 ne $curr_app_type) { prt("Overrode $key with [$curr_app_type], from [$tmp2]\n"); } } } $type = "NOT DEFINED"; $key = 'APP_TYPE'; $key = 'PROJECT_APTP' if (!defined ${$rh}{$key}); if (defined ${$rh}{$key}) { $type = ${$rh}{$key}; } # 2010-01-15 - get appropriate DSP file name (real = to replace existing, if any) $key = 'PROJECT_FILE'; $fprjf = ''; $rdspf = ''; $fdspf = ''; if (defined ${$rh}{$key}) { $fprjf = ${$rh}{$key}; ($nm,$dprjf,$ext) = fileparse($fprjf, qr/\.[^.]*/); $fdspf = $dprjf.$nm.".dsp"; # this may/should be ABSOLUTE } else { pgm_exit(1,"ERROR: key [$key] NOT IN hash! AND IT MUST BE!! Aborting!!!\n"); } # FIX20120718 - If NO project name, then use the input project file name as default if (!defined ${$rh}{'-NEW_PROJECT_NAME-'} && !defined ${$rh}{'PROJECT_NAME'}) { ${$rh}{'PROJECT_NAME'} = $nm; prt("No project name, so using project file name [$nm]!\n"); } $pnam = "NO PROJECT NAME"; $key = '-NEW_PROJECT_NAME-'; $key = 'PROJECT_NAME' if (!defined ${$rh}{$key}); if (defined ${$rh}{$key}) { $pnam = ${$rh}{$key}; # get the PROJECT NAME } # show_hash_results3($rh) if ($dbg_sl_04); # this would be BEFORE any changes made in chk_relative_paths... $key = '-NEW_PROJECT_NAME-'; $key = 'PROJECT_NAME' if (!defined ${$rh}{$key}); if (defined ${$rh}{$key}) { $pnam = ${$rh}{$key}; # get the PROJECT NAME $dsp = $pnam.".dsp"; # make a DSP file name ${$rh}{'PROJECT_DSPF'} = $dsp; $outd .= "\\" if ( !($outd =~ /[\\\/]$/) ); # ensure out directory ends '\' $out = $outd; # using OUT directory $out .= "temp.".$dsp; # form a TEMPORARY DSP file name fix_lib_list($rh); # crude game to ensure TEMP DSP name for this project is UNIQUE $cnt = 0; while ( is_in_array($out, @dsp_file_list) ) { $cnt++; # already have a DSP of that name, so $out = $outd; # get OUT directory again, and $out .= "temp.".$pnam.$cnt.".dsp"; # add a COUNT to name } if ($fix_rel_paths) { # ====================================================================================== # ok, need to change sources from perhaps '.\src.cxx' to '..\..\lib\src.cxx' - a big job # and LOTS of other things... # UGH - calling this HERE, is BEFORE the %results hash is built chk_relative_paths($rh,$outd,$vc_dir); # was $perl_base; # this can be changed by -dsp= # ====================================================================================== } else { prt("No relative path change: vcd=[$vc_dir] out=[$outd]\n") if (VERB9()); } # 2011-10-18 - Make other ADSJUTMENTS to DSP HASH adjust_inter_out_dirs($rh) if ($adj_inter); adjust_runtime_to($rh,$adj_rt) if (length($adj_rt)); adjust_output_name($rh) if ($adj_out); # remove like -NEW_LIBS- = [wsock32.lib comctl32.lib /libpath:"..\lib" /nodefaultlib:"libcmtd"] $tmp2 = ''; # clear $tmp2 delete_nodefaultlib_all($rh,\$tmp2) if ($del_ndl_all); if (length($tmp2) && VERB5()) { prt("[v5] Removed /nodefaultlib [$tmp2]\n"); } if ($dbg_sl_04 || VERB1()) { my $rh2 = show_hash_results3($rh); # if ($dbg_sl_04 || VERB5()) show_project_hash($rh2); } # *** WRITE DSP FILE - FIRST TO A 'TEMP' FILE, to do a compare, if needed *** # =========================================================================== if ($write_dsp > 0) { prt("Doing write_hash_to_DSP3 $out (debug=$dbg4write)\n") if (VERB9()); if ( write_hash_to_DSP3( $out, $rh, $dbg4write ) ) { push(@dsp_file_list,$out); # store name # project_list 0 1 2 #push(@project_list, [ $tmp, $dsp, $out ]); push(@project_list, [ $pnam, $fdspf, $out ]); $key = 'PROJECT_FILE'; if (defined ${$rh}{$key}) { $prjf = ${$rh}{$key}; prt( "For '$prjf' written '$out'\n" ) if (VERB5()); # Uses cmp2dsps[?].pl, external to here... if ($comp_2_dsps) { ($nm,$dir,$ext) = fileparse($prjf, qr/\.[^.]*/); $dspf = $dir.$nm.".dsp"; if (( -f $dspf)&&( -f $out)) { $msg = "cmp2dsps $dspf $out"; $msg .= " -l" if ($load_log); prt("Doing $msg...\n"); system("$msg"); } else { $msg = "No compare done! "; if ( !(-f $dspf) ) { $msg .= "Missing [$dspf]?"; } if ( !(-f $out) ) { $msg .= "Missing [$out]??"; } prtw("WARNING: $msg\n"); } } # ======================================= } } else { prtw("WARNING: No DSP written for [$pnam] project.\n" ); } } else { prt("Project: $pnam: No DSP written - Use -dsp[:dsp_dir] to enable!\n"); } } else { if ($dbg_sl_04 || VERB1()) { my $rh2 = show_hash_results3($rh); # if ($dbg_sl_04 || VERB5()) show_project_hash($rh2); } prtw("WARNING: NO PROJECT NAME! = NO DSP WRITTEN!\n"); } if (do_hash_cmake_test($rh)) { prtw("WARNING: PROJECT $pnam $type FAILED CMAKE HASH TEST!\n"); } else { my $rcph = get_cmake_proj_hash_ref(); # = return \@my_cmake_proj_hashes; push(@{$rcph},$rh); # add $rh to @my_cmake_proj_hashes prt("Added: PROJECT $pnam $type my_cmake_proj_hashes\n"); } push(@proj_hash_array,$rh); return $rh; } sub fix_rel_path2($$) { my ($root,$rel) = @_; my $cd = cwd(); my ($fp,$msg,$tmp); if (chdir($root)) { $fp = File::Spec->rel2abs($rel); # we are IN the SLN directory, get ABSOLUTE from RELATIVE chdir($cd); # and get us back to where we were... $msg = "1:File::Spec:"; } else { $fp = fix_rel_path3($root.$rel,'fix_rel_path2'); # else use internal service $msg = "2:fix_rel_path3:" } if (-f $fp) { $msg .= " ok"; } else { $msg .= " NOT FOUND"; if ($fp =~ /\\SimGear\.cs\\/) { $tmp = $fp; $tmp =~ s/\\SimGear\.cs\\/\\SimGear-cs\\/; if (-f $tmp) { $fp = $tmp; $msg = "ok $msg"; } } if ($msg =~ /^1/) { $tmp = fix_rel_path3($root.$rel,'fix_rel_path2'); # else use internal service if (-f $tmp) { $fp = $tmp; $msg .= ", but OK with fix_rel_path3!!!"; } else { $msg .= ", NOR from fix_rel_path3 [$tmp]" } } } prt("From: [$root] [$rel], got [$fp] $msg\n") if ($dbg_sl_14); return $fp; # hopefully, return ABSOLUTE path } # Read and store contents of SOLUTION (.sln) file # 22/04/2008 - Extract DEPENDENCIES from solution file, and add to DSW output # 24/11/2010 - Support for VC10 XML files sub process_SLN_file2($) { my ($sln_fil_in) = shift; my ($cnt, $line, $vers, @arr, $mver, $par, $ff, $itmnum); my ($projname, $projfile, $projff, $gotproj, $relpath); my ($tnm,$tpth); my ($inproj, $tline, $projid, $inpdeps, $projdeps); my ($nmdeps, $depid, $pn, $fnd, $list); my ($msg,$text,$dspfile,$fdspfil,$name); my $fil = File::Spec->rel2abs($sln_fil_in); open IF, "<$fil" or mydie( "ERROR: Unable to open [$fil]... $! ...\n" ); my @lines = ; close IF; $cnt = scalar @lines; ($name,$sln_path) = fileparse($fil); # get the NAME, and SOLUTION PATH (should be ABSOLUTE, NOT relative) my %hash = (); my %sln_projects = (); my %sln_projpath = (); my %sln_depends = (); my %sln_projids = (); my %missed_vcprojs = (); prt( "\nProcessing $cnt lines ... n=[$name] p=[$sln_path] ...\n" ) if (VERB1()); $projname = ''; $projfile = ''; $projff = ''; $gotproj = 0; $inproj = 0; $inpdeps = 0; foreach $line (@lines) { $tline = trim_all($line); if ($line =~ /.+Format\s+Version\s+(\d+\.\d+)$/i) { $vers = $1; # get n.nn version @arr = split(/\./,$vers); $mver = $arr[0]; prt( "Is MSVC Version $mver ...\n" ); } elsif ($line =~ /^Project\s*\(/) { # seek like #Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ALL_BUILD", "ALL_BUILD.vcxproj", "{4BB0374F-3B6E-4EC8-9BE0-4BE8947B80E3}" #Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "abyss.vcproj", "{8B384B8A-2B72-4DC4-8DF1-E3EF32F18850}" #Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fgadmin", "fgadmin\fgadmin.vcxproj", "{7004E589-7EA0-4AFD-B432-3D5E00B55049}" # ProjectSection(ProjectDependencies) = postProject # {22540CD3-D3CA-4C86-A773-80AEEE3ACDED} = {22540CD3-D3CA-4C86-A773-80AEEE3ACDED} # EndProjectSection #EndProject ###prt( "Got project [$line] ...\n" ); $inproj = 1; @arr = split( '=', $line ); $cnt = scalar @arr; if ($cnt == 2) { $par = $arr[1]; # get 2nd part, like say '"abyss", "abyss.vcproj", "{8B384B8A-2B72-4DC4-8DF1-E3EF32F18850}"' @arr = split(',', $par); $cnt = scalar @arr; if ($cnt == 3) { $projname = strip_quotes(trim_all($arr[0])); # project NAME $projfile = strip_quotes(trim_all($arr[1])); # vcproj FILE (sometimes) $projid = strip_quotes(trim_all($arr[2])); # project ID $projff = fix_rel_path2($sln_path,$projfile); # return ABSOLUTE # if ((length($projname)) && (is_vcproj_ext($projfile)) && (-f $projff)) { # 01/12/2010 - Remove need for the file to EXIST #if ((length($projname)) && (is_vcproj_ext($projfile)) ) { if ((length($projname)) && (is_vcproj_ext($projfile) || is_vcxproj_ext($projfile)) ) { if (-f $projff) { # and file } else { $missed_vcprojs{$projname} = $projff; } $gotproj = 1; ($tnm,$tpth,$text) = fileparse($projff,qr/\.[^.]*/); $fdspfil = $tpth.$tnm.".dsp"; # this is a DSP EQUIVALENT to the vcproj location # BUT, we may have been given a DIFFERENT DSP output dir through # -dsp= ($out_dsp_dir) and $g_had_dsp, and maybe '-fix-rel' ($fix_rel_paths) if ($g_had_dsp) { $fdspfil = $out_dsp_dir; $fdspfil .= "\\" if ( !($fdspfil =~ /(\\|\/)$/) ); $fdspfil .= $tnm.".dsp"; } $relpath = get_rel_dos_path($tpth, $sln_path); ($tnm,$tpth,$text) = fileparse($projfile,qr/\.[^.]*/); $dspfile = $tpth.$tnm.".dsp"; prt( "Got PROJECT name=$projname, file=[$projfile], ff=[$projff], rel=[$relpath].\n" ) if ($dbg_sl_01); if (defined $sln_projects{$projname}) { mydie( "A PROBLEM: Already GOT this project name $projname!!!\n" ); } else { $sln_projects{$projname} = $projff; # $sln_projpath{$projname} = $relpath; # can be BLANK, or say 'BvMath/' # 0 1 2 3 4 $sln_projpath{$projname} = [$projfile,$projff,$relpath,$dspfile,$fdspfil]; # relative project file, like '..\alut\path\alut.vcproj' prt( "Stored \$sln_projpath{$projname} = [0:$projfile,1:$projff,2:$relpath,3:$dspfile,4:$fdspfil]\n") if ($dbg_sl_15); $sln_projids{$projname} = $projid; $sln_depends{$projname} = ''; # start dependencies, if any if ($dbg_sl_16) { my $msg = $projname; $msg .= ' ' while (length($msg) < 24); $msg .= $projid; prt("$msg\n"); } } ### pgm_exit(1,"TEMP EXIT"); } else { # CARE: Vers 11 MSVC10 can have projects with NO file extension # Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lua51", "Lua51", "{1CBEAA34-BA34-497D-A775-B9AF6F905696}" # Seems these are project GROUPS, with no project file, so NO warning required if ($projname eq $projfile) { # forget these groups $gotproj = 1; # pretent we got the project } else { $msg = "WARNING: "; if (!length($projname)) { $msg .= "Failed to get a project name! "; } elsif ( !is_vcproj_ext($projfile) && !is_vcxproj_ext($projfile)) { $msg .= "Name [$projfile] NOT a VCPROJ nor VCXPROJ name! "; } else { $msg .= "Unable to locate file [$projff]! "; } $msg .= " Line is (trimmed)\n$tline"; prtw("$msg\n"); } } } else { prtw( "Warning: Part 2 of Project line did NOT split into 3 on comma!???\n" ); } } else { prtw( "Warning: Project line did NOT split in 2 on equal sign!???\n" ); } # to switch on $tryharder requires additional work on parsing this line # ===================================================================== prtw("WARNING: line [$line] ...\n") if (!$gotproj); # ===================================================================== } elsif ($inproj) { # in the Project section - look for END of section, and DEPENDENCIES # ProjectSection(ProjectDependencies) if ($tline eq 'EndProject') { ###if ($line =~ /^EndProject\s*/) $inproj = 0; } else { if ($inpdeps) { if ($tline eq 'EndProjectSection' ) { $inpdeps = 0; } else { # collect dependencies @arr = split( '=', $line ); $cnt = scalar @arr; if ($cnt == 2) { $arr[0] = trim_all($arr[0]); $arr[1] = trim_all($arr[1]); if ($arr[0] eq $arr[1]) { $projdeps = $sln_depends{$projname}; # extract dependencies, if any $projdeps .= '|' if (length($projdeps)); $projdeps .= $arr[0]; prt( "$pgmname: Proj $projname, dependant on $arr[0] ...\n" ) if ($dbg_sl_02); ##prt( "Proj $projname, dependant on $projdeps ...\n" ); $sln_depends{$projname} = $projdeps; } else { prtw( "Warning: Found different IDS '$arr[0]' NE '$arr[1]'!!! \n" ); } } else { prtw( "Warning: Project DEPENDENCY line did NOT split in 2 on equal sign!???\n" ); prtw( "line=$line" ); } } } elsif ($line =~ /ProjectSection\s*\(\s*ProjectDependencies\s*\)/) { $inpdeps = 1; } } } } ###prt( "Done $fil ... got ".scalar @proj_files." project files ...\n" ); prt( "Done $fil ... got ".scalar keys(%sln_projects)." project files ...\n" ); # resolve dependencies, if possible - warn if NOT ... #resolve_depends(); # Have STORED # $sln_projects{$projname} = $projff; # $sln_projpath{$projname} = $relpath; # can be BLANK, or say 'BvMath/' # 0 1 2 3 4 #$sln_projpath{$projname} = [$projfile,$projff,$relpath,$dspfile,$fdspfil]; # relative project file, like '..\alut\path\alut.vcproj' #prt( "Stored \$sln_projpath{$projname} = [0:$projfile,1:$projff,2:$relpath,3:$dspfile,4:$fdspfil]\n") if ($dbg_sl_15); # $sln_projids{$projname} = $projid; # $sln_depends{$projname} = ''; # start dependencies, if any foreach $projname (keys %sln_projects) { $projdeps = $sln_depends{$projname}; if (length($projdeps)) { # there is LENGTH, convert giant CID to simple project names @arr = split( /\|/, $projdeps ); # split em up $cnt = scalar @arr; # get count of split #prt( "Proj $projname, depends on $cnt = $projdeps ...\n" ); $nmdeps = ''; # build simple NAME set foreach $depid (@arr) { # find project MATCHING that ID, in full list of IDs $fnd = 0; $list = ''; foreach $pn (keys %sln_projids) { if ($pn ne $projname) { $projid = $sln_projids{$pn}; $list .= "|$projid"; if ($depid eq $projid) { $nmdeps .= '|' if (length($nmdeps)); $nmdeps .= $pn; $fnd = 1; last; } } } if (!$fnd) { prtw("Warning: Failed to FIND [$depid], in list \n[$list]\n!"); } } @arr = split( /\|/, $nmdeps ); prt( "$pgmname: proj $projname, depends on $nmdeps ...\n" ) if ($dbg_sl_03); if ($cnt != scalar @arr) { # YEEK - Does NOT match - OH WELL prtw( "WARNING: proj [$projname] with depends [$projdeps] Failed to get SAME count $cnt - got ".scalar @arr." on split [$nmdeps]\n" ); pgm_exit(1,""); } $sln_depends{$projname} = $nmdeps; } } # ==================================================================== $hash{'SOLUTION'} = $fil; # keep the SOLUTION files also $hash{'PROJECTS'} = { %sln_projects }; $hash{'PROJPATH'} = { %sln_projpath }; # array refs [$projfile,$projff,$relpath] $hash{'DEPENDS'} = { %sln_depends }; $hash{'PROJIDS'} = { %sln_projids }; $hash{'MISSED_FILES'} = { %missed_vcprojs }; # not found on DISK return \%hash; } sub remove_base_path($$) { my ($ln, $bs) = @_; my $len1 = length($ln); my $len2 = length($bs); if ($len1 < $len2) { return $ln; } my ($i,$c1,$c2); for ($i = 0; $i < $len2; $i++) { $c1 = lc(substr($ln,$i,1)); $c2 = lc(substr($bs,$i,1)); if ($c1 ne $c2) { return $ln; } } return substr($ln,$len2); } sub return_common_dir($$) { my ($d1,$d2) = @_; my ($ll,$k,$com); $com = ''; $ll = length($d1); $ll = length($d2) if (length($d2) < $ll); # get SHORTEST for ($k = 0; $k < $ll; $k++) { # process for SHORTEST length last if (lc(substr($d1,$k,1)) ne lc(substr($d2,$k,1))); # end on first NOT SAME $com .= substr($d1,$k,1); # else add to common } return $com; } sub get_common_dir($) { my ($rffh) = @_; my $cdir = ''; my @keys = keys %{$rffh}; my $kcnt = scalar @keys; my ($ky1,$ky2,$k,$com); for ($k = 0; ($k+1) < $kcnt; $k++) { $ky1 = $keys[$k]; $ky2 = $keys[$k+1]; $com = return_common_dir($ky1,$ky2); if (length($com) == 0) { return ""; # no COMMON } if (length($cdir)) { $com = return_common_dir($com,$cdir); if (length($com) == 0) { return ""; # no COMMON } } $cdir = $com; # update the COMMON } return $cdir; } # sub mycmp_decend { sub mysort2 { return 1 if (${$a}[2] lt ${$b}[2]); return -1 if (${$a}[2] gt ${$b}[2]); return 0; } sub mysort0 { return -1 if (lc(${$a}[0]) lt lc(${$b}[0])); return 1 if (lc(${$a}[0]) gt lc(${$b}[0])); return 0; } sub sort_ref_results_by_type($) { my ($rr) = @_; my @arr = sort mysort2 @{$rr}; return \@arr; } sub sort_ref_results_by_name($) { my ($rr) = @_; my @arr = sort mysort0 @{$rr}; return \@arr; } sub show_sln_results($) { my ($rsh) = @_; my ($cnt,$min1,$min2,$min3,$cnt2); my ($val,$val2,$val3,$len); my ($k,$i,$dspf,$j); my ($tdsp,$vcpf); $k = 'RESULTS'; if (! defined ${$rsh}{$k}) { prtw("WARNING: Soluion hash reference does NOT contain [$k]!\n"); return 1; } # push(@results, [$k, $nm, $captyp, $ff]); # stored in 'RESULTS' # 0 1 2 3 4 5 6 # push(@results, [$k, $nm, $captyp, $relpf, $fdspf, 0, 0]); # stored in 'RESULTS' my $results = ${$rsh}{$k}; $k = 'PROJECT_LIST'; if (! defined ${$rsh}{$k}) { prtw("WARNING: Soluion hash reference does NOT contain [$k]!\n"); return 1; } my $plist = ${$rsh}{$k}; $k = 'PROJECT_FILE'; if (! defined ${$rsh}{$k}) { prtw("WARNING: Soluion hash reference does NOT contain [$k]!\n"); return 1; } my $in = ${$rsh}{$k}; $cnt = scalar @{$results}; if ($cnt == 0) { prt("\nNo projects found!\n"); return; } # get lengths, for neat output $min1 = 0; $min2 = 0; $min3 = 0; # 0 1 2 4 # push(@project_list, [ $tmp, $dsp, $out, $fdspf]); $cnt2 = scalar @{$plist}; # 0 1 2 3 4 5 6 # push(@results, [$name, $file, $type, $relpf, $fdspf, 0, 0]); # stored in 'RESULTS' if ($sort_by_name) { $results = sort_ref_results_by_name($results); } if ($sort_by_type) { $results = sort_ref_results_by_type($results); } my %types = (); for ($i = 0; $i < $cnt; $i++) { $val = ${$results}[$i][0]; $val2 = ${$results}[$i][1]; $val3 = ${$results}[$i][2]; $len = length($val); $min1 = $len if ($len > $min1); $len = length($val2); $min2 = $len if ($len > $min2); $len = length($val3); $min3 = $len if ($len > $min3); if (defined $types{$val3}) { $types{$val3}++; } else { $types{$val3} = 1; } } prt("\nSolution file [$in], has $cnt projects...($cnt2)\n"); if (VERB1()) { if ($cnt) { # about to output something like # testcon testcon.vcproj Console Application testcon.dsp (C:\GTools\perl\temp.testcon.dsp) # Setup a HEADING line $val = "Name"; $val2 = "File"; $val3 = "Type"; $val .= ' ' while (length($val) < $min1); $val2 .= ' ' while (length($val2) < $min2); $val3 .= ' ' while (length($val3) < $min3); prt("$val $val2 $val3"); # set HEADINGS prt(" DSP File") if (VERB5()); prt("\n"); } for ($i = 0; $i < $cnt; $i++) { $val = ${$results}[$i][0]; # extract the project NAME $dspf = 'UNKNOWN'; $tdsp = $dspf; for ($j = 0; $j < $cnt2; $j++) { if (${$plist}[$j][0] eq $val) { $dspf = ${$plist}[$j][1]; $tdsp = ${$plist}[$j][2]; last; } } $val2 = ${$results}[$i][1]; $val3 = ${$results}[$i][2]; # 0 1 2 3 4 5 6 # push(@results, [$projfile,$projff,$relpath,$dspfile,$fdsp, 0, 0]); # relative project file, like '..\alut\path\alut.dsp' $vcpf = ${$results}[$i][3]; # destination, relative DSP file, for DSW write if ($tdsp ne $dspf) { $dspf = "$dspf ($tdsp)"; } $val .= ' ' while (length($val) < $min1); $val2 .= ' ' while (length($val2) < $min2); $val3 .= ' ' while (length($val3) < $min3); #prt("$val $val2 $val3 $dspf\n"); # tgvpf tgvpf.vcproj Console Application .\tgvpf.dsp (C:\FG\28\terragear-cs\projects\msvc\temp.tgvpf.dsp) [tgvpf\tgvpf.dsp] prt("$val $val2 $val3\n"); ###prt(" $dspf [$vcpf]") if (VERB5()); ###prt("\n"); } } prt("Counts per type: "); foreach $val (keys %types) { if (length($val) == 0) { prt(" = $types{$val} "); } else { prt("$val = $types{$val} "); } } prt("\n"); prt( "$pgmname: Done $cnt vcproj processing...\n" ) if (VERB1()); } # If an $out directory given, try to adjust all SOURCE relative to this folder sub sln_file_processing($$$) { my ($flg,$in,$out) = @_; my ($k,$rsh,$val,$ff,$key,$captyp,$nm,$dir,$cnt,$i,$min1,$min2,$val2,$len); my ($refhash,$min,$cnt2,$dspf,$j,$val3,$min3,$ok); my ($ext,$k2,$relpf,$fdspf); my @results = (); ($nm,$sln_root_dir) = fileparse($in); $rsh = process_SLN_file2($in); if (VERB9()) { prt( "$pgmname: KEYS in SLN hash = " ); foreach $k (keys %{$rsh}) { prt( "$k " ); } prt("\n"); } # ===================================== $k = 'PROJECTS'; $k2 = 'PROJPATH'; if ((defined ${$rsh}{$k})&&(defined ${$rsh}{$k2})) { # $sln_projects{$projname} = $projff; $val = ${$rsh}{$k}; # extract projects HASH $val2 = ${$rsh}{$k2}; # extract project paths HASH $min = 0; $cnt = 0; $min1 = 0; my %ffhash = (); foreach $k (keys %{$val}) { $ff = ${$val}{$k}; $len = length($k); $min = $len if ($len > $min); if (is_vcproj_ext($ff) || is_vcxproj_ext($ff)) { $ffhash{$ff} = 1; $cnt++; } else { $ffhash{$ff} = 0; } $len = length($ff); $min1 = $len if ($len > $min1); } $commdir = get_common_dir( \%ffhash ); if (length($commdir)) { prt("All $cnt vcproj files in a COMMON PATH: [$commdir]\n"); if (length($commdir) < $min1) { $min1 -= length($commdir); } } prt("SLN path=[$sln_root_dir]\n") if ($commdir ne $sln_root_dir); if (VERB1()) { foreach $k (keys %{$val}) { $ff = ${$val}{$k}; # 0 1 2 3 # $sln_projpath{$projname} = [$projfile,$projff,$relpath,$dspfile]; # relative project file, like '..\alut\path\alut.dsp' # and later # push(@results, [$k, $nm, $captyp, $relpf, $fdspf]); # stored in 'RESULTS' $val3 = ${$val2}{$k}; $relpf = ${$val3}[3]; # relative DSP file, for DSW write $ok = (( -f $ff ) ? "ok" : "NOT FOUND!"); ($nm, $dir, $ext) = fileparse( $ff, qr/\.[^.]*/ ); $dspf = $dir.$nm.".dsp"; $ok .= "2" if (-f $dspf); $ff = remove_base_path($ff,$commdir) if (length($commdir)); $k .= ' ' while (length($k) < $min); $ff .= ' ' while (length($ff) < $min1); prt("$k - $ff ($ok) $relpf\n" ); # this DSP rel.path may need to be changed later, if -dsp= } prt( "\nNow to process EACH of the $cnt projects...\n" ); } # -------------------------------------------------- foreach $k (keys %{$val}) { $ff = ${$val}{$k}; # prt("$k - $ff\n" ); ($nm, $dir) = fileparse($ff); # if (is_vcproj_ext($ff)) # 01/12/2010 - add an existance check #if (is_vcproj_ext($ff) && (-f $ff)) { # 14/04/2012 - add check for vcxproj if (-f $ff) { if (is_vcproj_ext($ff)) { $refhash = process_vcproj_file($ff, $out); } elsif (is_vcxproj_ext($ff)) { $refhash = process_vcxproj_file($ff, $out); } $key = 'APP_TYPE'; if ( ! defined ${$refhash}{$key}) { $key = 'PROJECT_APTP'; } if (defined ${$refhash}{$key}) { $captyp = ${$refhash}{$key}; } else { $captyp = "Unknown - key=[$key] NOT SET"; } # 0 1 2 3 4 # $sln_projpath{$projname} = [$projfile,$projff,$relpath,$rdsp,$fdsp]; # relative project file, like '..\alut\path\alut.dsp' $val3 = ${$val2}{$k}; $relpf = ${$val3}[3]; # relative DSP file, for DSW consumption (see write_proj_DSW3) $fdspf = ${$val3}[4]; if ($fix_rel_paths && $g_had_dsp) { my ($tn,$td) = fileparse($relpf); $relpf = ".\\$tn"; } # 0 1 2 3 4 5 6 push(@results, [$k, $nm, $captyp, $relpf, $fdspf, 0, 0]); # stored in 'RESULTS' } } } else { pgm_exit(1,"ERROR: key [$k] NOT found in hash!\n"); } $k = 'RESULTS'; ${$rsh}{$k} = [@results]; $k = 'PROJECT_LIST'; ${$rsh}{$k} = [@project_list]; # keep project list, including output DSP file, if written $k = 'PROJECT_FILE'; ${$rsh}{$k} = $in; return $rsh; } # ============================================== # 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_xml_ref_array($$) { my ($ff,$rla) = @_; my $max = scalar @{$rla}; my ($i,$line,$len,$ch,$inquote,$qc,$tag,$txt,$intag,$lnn,$dnline); $inquote = 0; $intag = 0; my @xlines = (); $lnn = 0; $tag = ''; $txt = ''; $dnline = 0; foreach $line (@{$rla}) { chomp $line; # = trim_all($line); $len = length($line); $lnn++; $dnline = 0; for ($i = 0; $i < $len; $i++) { $ch = substr($line,$i,1); if ($inquote) { if ($intag) { $tag .= $ch; } else { $txt .= $ch; } if ($ch eq $qc) { $inquote = 0; } } else { if ($intag) { $tag .= $ch; if ($ch eq '>') { $intag = 0; push(@xlines,[$lnn,$txt,$tag,$dnline]); $txt = ''; # clear text $tag = ''; # and tag $dnline++; } elsif (($ch eq '"') || ($ch eq "'")) { $qc = $ch; $inquote = 1; } } else { if ($ch eq '<') { $tag = $ch; $intag = 1; } else { $txt .= $ch; if (($ch eq '"') || ($ch eq "'")) { $qc = $ch; $inquote = 1; } } } } } if ($inquote) { prtw("WARNING:$lnn: Going to next line while in quotes [$qc]!\n file [$ff]\n"); $inquote = 0; } if (!$intag && (length($txt) || !$dnline)) { push(@xlines,[$lnn,$txt,$tag,$dnline]); $txt = ''; # clear any text } } return \@xlines; } sub write_xml_lines($$) { my ($ff,$rxml) = @_; my ($name,$dir) = fileparse($ff); my $tmp_out = $temp_dir.$PATH_SEP."temp.$name.xml"; my $cnt = scalar @{$rxml}; if ($cnt == 0) { prt("Array for [$ff] is BLANK!\n"); return; } my ($i,$rt,$msg,$lnn,$plnn,$txt,$tag); $msg = $curr_file_bom; $rt = ${$rxml}[0]; $plnn = ${$rt}[0]; $txt = ''; $tag = ''; for ($i = 0; $i < $cnt; $i++) { $rt = ${$rxml}[$i]; # 0 1 2 3 # push(@xlines,[$lnn,$txt,$tag,$dnline]); $lnn = ${$rt}[0]; $txt = ${$rt}[1]; $tag = ${$rt}[2]; if ($lnn != $plnn) { $msg .= "\n"; $plnn = $lnn; } $msg .= $txt; $msg .= $tag; } $msg .= "\n"; write2file($msg,$tmp_out); prt("Array written to [$tmp_out], for [$ff]\n"); } sub get_tag_hash($$) { my ($itag,$r2t) = @_; my $tag = $itag; my %h = (); my $len = length($tag); if ($len) { if (($tag =~ /^$/)) { $tag = substr($tag,1,$len-2); my @attribs = space_split($tag); $tag = $attribs[0]; ${$r2t} = $tag; my @arr = (); my $len = scalar @attribs; my ($i,$key,$val); for ($i = 1; $i < $len; $i++) { push(@arr,$attribs[$i]); } %h = array_2_hash_on_equals(@arr); } else { prtw("WARNING: Tag NOT complete [$tag]\n"); } } return \%h; } sub show_tag_hash($$$$) { my ($tag,$rh,$itag,$ra) = @_; my ($key,$val); my $rth = ${$rh}{'CURR_RTH'}; my $lnn = ${$rh}{'CURR_LNN'}; my $txt = trim_all(${$rh}{'CURR_TXT'}); my $cnt = scalar @{$ra}; #my $tag = ${$rh}{'CURR_TAG'}; #if (VERB9()) { if ($dbg_02) { prt("[02]$lnn: "); prt("Txt [$txt] ") if (length($txt)); prt("Tag [$tag] "); foreach $key (keys %{$rth}) { $val = ${$rth}{$key}; prt(" $key=$val"); } prt(" from [$itag]") if ($dbg_04); $txt = $cnt ? ${$ra}[-1] : "Empty"; prt(" nts [$txt]$cnt"); prt("\n"); } if ($dbg_09) { prt("[09]$lnn:$cnt:"); $cnt = 0; foreach $txt (@{$ra}) { $cnt++; prt(" $cnt"); prt("[$txt]"); } prt("\n"); } } sub set_curr_config($$) { my ($rh,$conf) = @_; prt("Setting CONFIG for [$conf]\n") if ($dbg_06); my $lnn = ${$rh}{'CURR_LNN'}; my $rcfgs = get_project_configs($rh); # 'PROJECT_CFGS' # short 'Release' full 'Release|Win32' # push(@{$rcfgs}, [ $confname, "", $conf, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS' my ($cfg,$tconf,$fnd,$dsp_sub_sub); $fnd = 0; foreach $cfg (@{$rcfgs}) { $tconf = ${$cfg}[2]; if ($conf eq $tconf) { $fnd = 1; $dsp_sub_sub = ${$cfg}[3]; prtw("$lnn: WARNING: Not a VALID \$dsp_sub_sub!\n") if (is_valid_dsp_sub_sub($dsp_sub_sub)); ${$rh}{'CURR_DSUB'} = $dsp_sub_sub; ${$rh}{'CURR_CFG'} = $conf; # like 'Release|Win32' etc last; } } if (!$fnd) { prt("$lnn: WARNING: Unable to locate CONFIG for [$conf]\n"); } } sub get_rt_value($$) { my ($rh,$test) = @_; if (!defined ${$rh}{'CURR_RTH'}) { pgm_exit(1,"ERROR: get_rt_value: passed ref.hash does NOT contain 'CURR'RTH'!\n"); } my $rt = ${$rh}{'CURR_RTH'}; my $lnn = ${$rh}{'CURR_LNN'}; my $fil = ${$rh}{'PROJECT_FDIR'}.${$rh}{'PROJECT_FILE'}; # = $nam.$ext; # 2010/05/07 - was $fil my $val = ''; if (defined ${$rt}{$test}) { $val = strip_quotes(${$rt}{$test}); # special for 'Condition' # # and if ($test eq 'Condition') { if ($val =~ /^\s*exists\('(.+)'\)/) { # TODO **TBD** mayeb load the 'Include file } else { prt("$lnn: Getting RT VALUE for 'Condition'\n") if ($dbg_06); my @arr = split(/==/,$val); if (scalar @arr == 2) { my $tmp = strip_single_quotes($arr[1]); $act_config = get_act_config_type($tmp); # test /Release/i and /Debug/i and others $val = "CONFIG=$tmp"; set_curr_config($rh,$tmp); } else { prtw("$lnn: WARNING: Condition did NOT split into 2 on '=='! [$val]! CHECK ME!\n file [$fil]\n"); } } } } return $val; } sub merge_library_list($) { my ($rh) = shift; my $rlibs = ${$rh}{'CURR_LIBS'}; # = \%liblist; my $rdirs = ${$rh}{'CURR_LDIRS'}; # = \%dirs; my $var1 = '-NEW_LIBS-'; my $dsp_sub_sub = ${$rh}{'CURR_DSUB'}; my $conf = ${$rh}{'CURR_CFG'}; my $lnn = ${$rh}{'CURR_LNN'}; my @arrd = keys(%{$rdirs}); my $dlist = ''; if (@arrd) { $dlist = join(" ",@arrd); $dlist = get_libpaths_string($dlist); } my @arr1 = keys(%{$rlibs}); my @arr2 = (); my ($clist,$lib); if (defined ${$dsp_sub_sub}{$var1}) { $clist = ${$dsp_sub_sub}{$var1}; @arr2 = split(/\s+/,$clist); } if (@arr1) { foreach $lib (@arr1) { next if (length($lib) == 0); push(@arr2,$lib) if (!is_in_array_nc($lib,\@arr2)); } } $clist = join(" ",@arr2); if (length($dlist)) { $clist .= " " if (length($clist)); $clist .= $dlist; } ${$dsp_sub_sub}{$var1} = $clist; prt("[v5] $lnn:SET: -NEW_LIBS-: cfg [$conf] = [$clist]\n") if (VERB5()); } # $seek = 'AdditionalIncludeDirectories'; # -NEW_INCS_[DBG|REL]- # sub get_default_sub3(0=rel,1=debug) { # ItemDef: ClCompile: AdditionalIncludeDirectories = [C:/FG/10/3rdparty/include;C:/Projects/lpng159/temp;C:/Projects/lpng159;%(AdditionalIncludeDirectories)], cond idg [CONFIG=Debug|Win32] op [] sub merge_inc_directories($$) { my ($rh,$txt) = @_; return if (length($txt) == 0); my $var1 = '-NEW_INCS-'; my $dsp_sub_sub = ${$rh}{'CURR_DSUB'}; my $conf = ${$rh}{'CURR_CFG'}; my $lnn = ${$rh}{'CURR_LNN'}; my @arr = split(/;+/,$txt); # my $istg = get_includes_string($txt); my $istg = ''; my ($inc); foreach $inc (@arr) { next if ($inc =~ /^%/); $istg .= ' ' if (length($istg)); $istg .= '/I "'.$inc.'"'; } my $ilist = ''; if (defined ${$dsp_sub_sub}{$var1}) { $ilist = ${$dsp_sub_sub}{$var1}; prtw("$lnn: WARNING: Need MERGE of old [$ilist], with [$istg]\n") if (length($ilist) && length($istg)); } ${$dsp_sub_sub}{$var1} = $istg; prt("[v5] $lnn:SET: -NEW_INCS-: cfg [$conf] = [$istg]\n") if (VERB5()); } sub split_defines_dlist($) { my $txt = shift; my @arr = split(/\/D\s+/,$txt); my $max = scalar @arr; my ($i,$def); for ($i = 0; $i < $max; $i++) { $def = $arr[$i]; $def = strip_quotes($def); $arr[$i] = $def; } return @arr; } # 94: ItemDef: ClCompile: PreprocessorDefinitions = [WIN32;_WINDOWS;_DEBUG;PNG_CONFIGURE_LIBPNG;_CRT_SECURE_NO_DEPRECATE;CMAKE_INTDIR="Debug";PNG_BUILD_DLL;%(PreprocessorDefinitions)], cond idg [CONFIG=Debug|Win32] op [] -NEW_DEFS- # LOTS of goodies like # _DEBUG;_WINDOWS;WIN32;_VISUALC_;NeedFunctionPrototypes;_LIB;WIN32;WIN32_LEAN_AND_MEAN;HAVE_WINCODEC_H;WEBP_USE_THREAD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) sub set_preprocessor_defines($$) { my ($rh,$txt) = @_; return if (length($txt) == 0); my $var1 = '-NEW_DEFS-'; my $dsp_sub_sub = ${$rh}{'CURR_DSUB'}; my $conf = ${$rh}{'CURR_CFG'}; my $lnn = ${$rh}{'CURR_LNN'}; my @arr2 = (); if (defined ${$dsp_sub_sub}{$var1}) { @arr2 = split_defines_dlist(${$dsp_sub_sub}{$var1}); } my @arr1 = split(/;+/,$txt); my ($def); foreach $def (@arr1) { next if ($def =~ /^%/); next if (length($def) == 0); $def = strip_quotes($def); next if (length($def) == 0); $def =~ s/"/"/g; push(@arr2,$def) if (!is_in_array($def,@arr2)); } my $list = ''; foreach $def (@arr2) { next if (length($def) == 0); $def = strip_quotes($def); next if (length($def) == 0); $list .= ' ' if (length($list)); $list .= "/D \"$def\""; # FIX20140103 Not /I but /D } ${$dsp_sub_sub}{$var1} = $list; prt("[v5] $lnn:SET: -NEW_DEFS-: cfg [$conf] to [$list]\n") if (VERB5()); } # 92: ItemDef: ClCompile: RuntimeLibrary = [MultiThreadedDebugDLL], cond idg [CONFIG=Debug|Win32] op [] -NEW_RT- sub set_runtime_library($$) { my ($rh,$txt) = @_; return if (length($txt) == 0); my $var1 = '-NEW_RT-'; my $dsp_sub_sub = ${$rh}{'CURR_DSUB'}; my $conf = ${$rh}{'CURR_CFG'}; my $lnn = ${$rh}{'CURR_LNN'}; my $rt = ''; my $crt = ''; my $msg = ''; if ($txt eq 'MultiThreadedDebugDLL') { $rt = "/MDd"; } elsif ($txt eq 'MultiThreadedDLL') { $rt = "/MD"; } elsif ($txt eq 'MultiThreaded') { $rt = "/MT"; } elsif ($txt eq 'MultiThreadedDebug') { $rt = "/MTd"; } if (length($rt)) { if (defined ${$dsp_sub_sub}{$var1}) { $crt = ${$dsp_sub_sub}{$var1}; if ($crt eq $rt) { $msg .= 'same as before'; } else { $msg .= "changed from [$crt]"; } } ${$dsp_sub_sub}{$var1} = $rt; prt("[v5] $lnn:SET: -NEW_RT-: cfg [$conf], to [$rt] $msg\n") if (VERB5()); } else { prtw("$lnn: WARNING: TODO: Set RUNTIME for cfg [$conf] for [$txt] FIX ME! 5\n"); } } # from CMake source # std::string configType = ""; # switch(this->Target->GetType()) # { # case cmTarget::SHARED_LIBRARY: # case cmTarget::MODULE_LIBRARY: # configType += "DynamicLibrary"; # break; # case cmTarget::OBJECT_LIBRARY: # case cmTarget::STATIC_LIBRARY: # configType += "StaticLibrary"; # break; # case cmTarget::EXECUTABLE: # configType += "Application"; # break; # case cmTarget::UTILITY: # configType += "Utility"; # break; # } # configType += "\n"; # PROJECT_APTP - application TYPE # $app_console_stg = 'Console Application' = get_dsp_head_console # $app_windows_stg = 'Application' = get_dsp_head_app # $app_dynalib_stg = 'Dynamic-Link Library' = get_dsp_head_dynalib # $app_statlib_stg = 'Static Library' = get_dsp_head_slib # $app_utility_stg = 'Utility' = *TBD* my %configs_shown = (); sub set_configuration_type($$) { my ($rh,$txt) = @_; return if (length($txt) == 0); my $lnn = ${$rh}{'CURR_LNN'}; pgm_exit(1,"ERROR: in set_configuration_type() \${\$rh}{'CURR_CFG'} NOT DEFINED!\n") if (!defined ${$rh}{'CURR_CFG'}); my $conf = ${$rh}{'CURR_CFG'}; my $app = ''; if ($txt eq 'DynamicLibrary') { $app = 'Dynamic-Link Library'; } elsif ($txt eq 'StaticLibrary') { $app = 'Static Library'; } elsif ($txt eq 'Application') { $app = 'Application'; } elsif ($txt eq 'Utility') { $app = 'Utility'; # $app_utility_stg = 'Utility' = *TBD* } if (length($app)) { ${$rh}{'PROJECT_APTP'} = $app; if (VERB9() || !defined $configs_shown{$conf}) { prt("$lnn:SET: project type [$app] for cfg [$conf]\n"); if (!defined $configs_shown{$conf}) { $configs_shown{$conf} = []; } my $ra = $configs_shown{$conf}; push(@{$ra},$app); } } else { prtw("$lnn: WARNING: Uncased ConfigurationType: [$txt]! FIX ME! 6\n"); } } sub process_rxml_vcxproj($$$) { my ($inff,$rxml,$outd) = @_; my ($vcname,$vcdir,$vcext) = fileparse($inff, qr/\.[^.]*/); my $tmp_out = $temp_dir.$PATH_SEP."temp.$vcname.xml"; my $cnt = scalar @{$rxml}; if ($cnt == 0) { prt("Array for [$inff] is BLANK!\n"); return; } my ($i,$rth,$rtx,$msg,$lnn,$plnn,$txt,$tag,$inproj,$incommand,$command,$initemgroup,$inpropgroup,$impgroup); my ($idefgroup,$rtag,$label,$val,$ptag,$show,$opcond,$pgcond,$tvers); my ($tver,$dtargs); # attribs of my ($ltag,$otag,$nxtstag,$tagtype,$attcnt,$idconf,$lnnbcmd,$tmp,$idopntag); my ($itemlabel,$pglabel,$inprojcfg,$incustom,$inmessage,$inprojref,$prjcfg); my ($dsp_sub_sub,$confname,$var1,$platform,$cdsub,$pcfginc,$relpath,$conf,$innone); my (@arr,$wmsg); my ($inprepro,$inrescomp,$RootNamespace); my ($inexcl,$inobjfname); # '-fix-rel' ($fix_rel_paths) my $fixrel = $fix_rel_paths; if (! -d $outd) { $fixrel = 0; # not valid destination for DSP file } $msg = $curr_file_bom; $tmp = ${$rxml}[0]; $plnn = ${$tmp}[0]; # get first line value $txt = ''; $tag = ''; $ptag = ''; $rtag = ''; $idopntag = ''; $itemlabel = ''; $pglabel = ''; $nxtstag = ''; $inproj = 0; $incommand = 0; $command = ''; $initemgroup = 0; $inpropgroup = 0; $idefgroup = 0; $impgroup = 0; $inprojcfg = 0; $incustom = 0; $inmessage = 0; $inprojref = 0; $inprepro = 0; $inrescomp = 0; $innone = 0; $inexcl = 0; $inobjfname = 0; $prjcfg = ''; $pcfginc = ''; $RootNamespace = ''; my $inoptim = 0; my $inbasicrtc = 0; $tvers = 'UNKNOWN'; $val = '*\$val NOT SET*'; my @sources = (); my @tag_stack = (); my $rh = get_default_ref_hash($inff); # get the DEFAULT reference HASH - lib_vcscan.pl my $rcfgs = get_project_configs($rh); # 'PROJECT_CFGS' # just name like 'Release' full name 'Debug|Win32' # prt("[v40] STORE:$tmp: In rcfgs (ra)[$confname], [$var1], [$conf], & \$dsp_sub_sub ] )\n") if ($dbg_v40); # ONLY STORE OF 'PROJECT_CFGS' # push(@{$rcfgs}, [ $confname, $var1, $conf, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS' # ${$rh}{'PROJECT_CCNT'}++; # count of stored 'PROJECT_CFGS # ${$rh}{'CURR_DSUB'} = $dsp_sub_sub; ${$rh}{'CURR_DCFG'} = 0; # no configuration done yet ${$rh}{'PROJECT_NAME'} = $vcname; # always have a NAME, even if it is the project file name for ($i = 0; $i < $cnt; $i++) { $rtx = ${$rxml}[$i]; # 0 1 2 3 # push(@xlines,[$lnn,$txt,$tag,$dnline]); $lnn = ${$rtx}[0]; $txt = ${$rtx}[1]; $tag = ${$rtx}[2]; ${$rh}{'CURR_LNN'} = $lnn; ${$rh}{'CURR_TXT'} = $txt; ${$rh}{'CURR_TAG'} = $tag; if ($lnn != $plnn) { $msg .= "\n"; } $msg .= $txt; $msg .= $tag; if ($inproj) { # SETUP # ============================== #if ($incommand && ($initemgroup || $idefgroup)) { if ($incommand) { # STAY to complete the command!!! $command .= "\n" if ($lnn != $plnn); $command .= $txt; if ($tag =~ /<\/Command>$/) { $ptag = $rtag; $rth = get_tag_hash($tag,\$rtag); ${$rh}{'CURR_RTH'} = $rth; show_tag_hash($rtag,$rh,$tag,\@tag_stack); $otag = substr($rtag,1); if (@tag_stack) { $ltag = pop @tag_stack; $nxtstag = ((@tag_stack) ? $tag_stack[-1] : "EMPTY STACK"); prt("[09] POPPED [$ltag] from tag_stack. nxt [$nxtstag] incommand\n") if ($dbg_09); if ($otag ne $ltag) { prtw("WARNING: $lnn: Got close [$otag], but last on stack is [$ltag]! nxt [$nxtstag]\n file [$inff]\n"); } } else { $nxtstag = "EMPTY STACK"; prtw("WARNING: $lnn: Got close [$otag], but NONE ON STACK!\n file [$inff]\n"); } prt("$lnn: CLOSE tag $otag [$tag] next [$nxtstag]\n") if ($dbg_03); if (VERB9()) { prt("$command\n") if ($dbg_01); $tmp = length($command); prt("$lnn:[v9]: End command bgn=$lnnbcmd, len=$tmp\n"); } if ($initemgroup) { prt("[10] $lnn:fall through to UNSET incommnd\n") if ($dbg_10); } else { $command = ''; $incommand = 0; # this done LATER prt("\n[10] $lnn: CLEARED incommnd\n\n") if ($dbg_10); } } else { next; } } else { $ptag = $rtag; $rth = get_tag_hash($tag,\$rtag); ${$rh}{'CURR_RTH'} = $rth; show_tag_hash($rtag,$rh,$tag,\@tag_stack); $attcnt = scalar keys(%{$rth}); # get attribute COUNT for tag - note for <... /> the '/' is counted if (defined ${$rth}{'/'}) { prt("$lnn: COMP tag $rtag [$tag]\n") if ($dbg_03); $tagtype = 0; # a compete TAG } elsif ($rtag =~ /^\//) { $tagtype = 1; # a close TAG $otag = substr($rtag,1); if (@tag_stack) { $ltag = pop @tag_stack; $nxtstag = ((@tag_stack) ? $tag_stack[-1] : "EMPTY STACK"); prt("[09] POPPED [$ltag] from tag_stack. nxt [$nxtstag]\n") if ($dbg_09); if ($otag ne $ltag) { prtw("WARNING: $lnn: Got close [$otag], but last on stack is [$ltag]!\n file [$inff]\n"); } } else { prtw("WARNING: $lnn: Got close [$otag], but NONE ON STACK!\n file [$inff]\n"); } prt("$lnn: CLOSE tag $otag [$tag] next [$nxtstag]\n") if ($dbg_03); } elsif ($rtag =~ /\/$/) { # self-closing tag - like - do NOT add to stack $tagtype = 0; # a compete TAG } else { $opcond = get_rt_value($rh,'Condition'); $tagtype = 2; # an open tag $nxtstag = ((@tag_stack) ? $tag_stack[-1] : "EMPTY STACK"); prt("$lnn: OPEN tag $rtag [$tag] prev [$nxtstag]\n") if ($dbg_03); push(@tag_stack,$rtag); prt("[09] ADDED [$rtag] to tag_statck prev [$nxtstag] itmg=$initemgroup idefg=$idefgroup pgrp=$inpropgroup impgrp=$impgroup\n") if ($dbg_09); } } # ====================================================================== # after SETUP # ======================================================================= # 1 = ItemGroup if ($initemgroup) { if ($incommand) { # $command .= "\n" if ($lnn != $plnn); # $command .= $txt; if ($tag =~ /<\/Command>$/) { #if (VERB9()) { # prt("$command\n") if ($dbg_01); # prt("$lnn:[v9]: End command\n"); #} $command = ''; $incommand = 0; prt("\n[10] $lnn: CLEARED incommnd initemgroup\n\n") if ($dbg_10); } } else { if ($tag =~ /^<\/ItemGroup>/) { prt("$lnn:[v9]: End ItemGroup\n") if (VERB9()); $initemgroup = 0; ${$rh}{'CURR_DCFG'} = 1; if ($itemlabel eq "ProjectConfigurations") { # no configuration done yet ${$rh}{'CURR_DCFG'} = 1; if (VERB9()) { prt("$lnn: ProjectConfigurations: "); prt("Got ".${$rh}{'PROJECT_CCNT'}." configs."); # count of stored 'PROJECT_CFGS $rcfgs = get_project_configs($rh); # 'PROJECT_CFGS' # short 'Release' full 'Release|Win32' # push(@{$rcfgs}, [ $confname, "", $val, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS' foreach $tmp (@{$rcfgs}) { prt(" ".${$tmp}[2]); } prt("\n"); } } } elsif ($tag =~ /^setlocal # "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -HC:/FG/10/flightgear -BC:/FG/10/flightgear/build --check-stamp-file C:\FG\10\flightgear\build\src\FDM\YASim\CMakeFiles\generate.stamp # if %errorlevel% neq 0 goto :cmEnd $incommand = 1; prt("\n[10] $lnn:initemgroup: SETTING incommnd\n\n") if ($dbg_10); prt("$lnn:[v9]: ItemGroup\n") if (VERB9()); $lnnbcmd = $lnn; $command = ''; } elsif ($inprojcfg || ($itemlabel eq 'ProjectConfigurations')) { # # # Debug # Win32 # # # Release # Win32 # # if ($rtag eq 'ProjectConfiguration') { # $pcfginc = get_rt_value($rh,'Include'); $inprojcfg = 1; ${$rh}{'CURR_CONF'} = ''; ${$rh}{'CURR_CON1'} = ''; } elsif ($rtag eq '/ProjectConfiguration') { $confname = ${$rh}{'CURR_CONF'}; # Configuration $platform = ${$rh}{'CURR_CON1'}; # Platform if ( length($platform) && length($confname) ) { $val = $confname.'|'.$platform; # join Configuration|Platform $tmp = get_act_config_type($confname); # test /Release/i and /Debug/i and others $dsp_sub_sub = get_default_sub3($tmp); $rcfgs = get_project_configs($rh); # 'PROJECT_CFGS' # short 'Release' full 'Release|Win32' push(@{$rcfgs}, [ $confname, "", $val, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS' ${$rh}{'PROJECT_CCNT'}++; # count of stored 'PROJECT_CFGS ${$rh}{'CURR_DSUB'} = $dsp_sub_sub; prtw("WARNING: ProjectCOnfiguration Include=$pcfginc NOT EQUAL merge [$val]!\n") if ($pcfginc ne $val); if (VERB5() || $dbg_05) { prt("$lnn: [v5] STORED:$tmp:".${$rh}{'PROJECT_CCNT'}.": "); prt("[[$confname], [], [$val], \$dsp_sub_sub ] cmp [$pcfginc]\n"); } } else { prtw("WARNING: $lnn: CONFIG NOT CREATED! WHY? [$tag]\n"); } $inprojcfg = 0; } elsif (($rtag eq 'Configuration')||($rtag eq 'Platform')) { # entering... } elsif ($rtag eq '/Configuration') { ${$rh}{'CURR_CONF'} = $txt; } elsif ($rtag eq '/Platform') { ${$rh}{'CURR_CON1'} = $txt; } else { prtw("WARNING: $lnn:ItemGroup: tag text $val = $txt NOT HANDLED! FIX ME! 7\n"); } } elsif (($tag =~ /^ # # $val = get_rt_value($rh,'Include'); if ($val && length($val)) { ####$last_src = strip_dotrel(strip_quotes(trim_all($var1))); my ($last_src,$last_nm,$last_dir,$last_ext,$fname,$flist,$src_ref,$ok,$ff); $last_src = $val; if ($val =~ /^\w{1}:/) { $ff = $val; } else { $ff = $vcdir; $ff .= $PATH_SEP if (!($ff =~ /(\\|\/)$/)); $ff .= $val; } $ff = path_u2d($ff); $ff = fix_rel_path($ff); $ok = 'NF'; $ok = 'ok' if (-f $ff); # Prior to MSVC10 this was a RELATIVE PATH - like # # this is the RELATIVE PATH - relative to the vcproj file being scanned # Now would be a good time to ADJUST this PATH, for any NEW location # of the final DSP file!!! BUT, this is done back in vcproj05.pl # in the sub chk_relative_paths()... # BUT in MSVC10 this 'can' be an absolute path, like # C:\FG\10\flightgear\src\FDM\YASim\Wing.cpp # ========================= if ($fixrel) { my $cd = cwd(); # prt("Last source [$last_src]\n"); if ( ( -d $outd ) && chdir($outd) ) { $last_src = File::Spec->rel2abs($last_src); # we are IN the SLN directory, get ABSOLUTE from RELATIVE chdir($cd); # and get us back to where we were... } } ($last_nm,$last_dir,$last_ext) = fileparse( $last_src, qr/\.[^.]*/ ); # ========================= if ($fixrel) { $relpath = get_relative_path4($last_dir,$outd); $last_src = $relpath.$last_nm.$last_ext; } $fname = ''; $flist = ''; $src_ref = get_project_srcs_ref($rh); # 'PROJECT_SRCS' ${$rh}{'CURR_LOFF'} = scalar @{$src_ref}; # get current source OFFSET # ====================== # *** STORING SOURCE *** # ====================== if ($ok eq 'ok') { push(@{$src_ref}, [ $last_src, $fname, $flist, 0, '' ]); # and PUSH onto SOURCE stack ${$rh}{'CURR_LSRC'} = $last_src; ${$rh}{'CURR_LNME'} = $last_nm; ${$rh}{'CURR_LDIR'} = $last_dir; ${$rh}{'CURR_LEXT'} = $last_ext; if ($last_src eq $val) { prt("[v1] $lnn: SOURCE: [$val] $ok\n") if (VERB1()); } else { prt("[v1] $lnn: SOURCE: [$last_src] [$val] $ok\n") if (VERB1()); } push(@sources,[$last_src,$val]); } else { prt("$lnn: SRC NOT FOUND: [$last_src] [$val] $ok\n"); } } else { prtw("WARNING: $lnn: No Include [$tag] CHECKME\n"); } } else { $show = 0; if (($rtag eq 'CustomBuild')||($rtag eq 'CustomBuildStep')) { $incustom = 1; } elsif (($rtag eq '/CustomBuild')||($rtag eq '/CustomBuildStep')) { $incustom = 0; } elsif (($rtag eq 'Message')||($rtag eq 'WarningLevel')) { $inmessage = 1; } elsif (($rtag eq '/Message')||($rtag eq '/WarningLevel')) { $inmessage = 0; } elsif ($rtag eq 'ProjectReference') { $inprojref = 1; } elsif ($rtag eq '/ProjectReference') { $inprojref = 0; } elsif ($rtag eq 'PreprocessorDefinitions') { $inprepro = 1; } elsif ($rtag eq '/PreprocessorDefinitions') { $inprepro = 0; } elsif ($rtag eq 'ResourceCompile') { $inrescomp = 1; } elsif ($rtag eq '/ResourceCompile') { $inrescomp = 0; } elsif ($rtag eq 'ExcludedFromBuild') { $inexcl = 1; } elsif ($rtag eq '/ExcludedFromBuild') { $inexcl = 0; } elsif ($rtag eq 'ObjectFileName') { $inobjfname = 1; } elsif ($rtag eq '/ObjectFileName') { $inobjfname = 0; } elsif ($rtag eq 'Optimization') { $inoptim = 1; } elsif ($rtag eq '/Optimization') { $inoptim = 0; } elsif ($rtag eq 'BasicRuntimeChecks') { $inbasicrtc = 1; } elsif ($rtag eq '/BasicRuntimeChecks') { $inbasicrtc = 0; } elsif ($rtag eq 'CompileAs') { $inrescomp = 1; # $incompas = 1; } elsif ($rtag eq '/CompileAs') { $inrescomp = 0; # $incompas = 0; } elsif (($rtag eq 'None') && ($tagtype == 0)) { $innone++; } else { if ($incustom || $inmessage || $inprojref || $inprepro || $inrescomp || $inexcl || $inobjfname || $inoptim || $inbasicrtc ) { if ($rtag =~ /^\//) { $val = substr($rtag,1); prt("$lnn:[v9] ItemGroup: tag text $val = $txt\n") if (VERB9()); if ($incustom) { # already collecting the command } elsif ($inmessage) { # nothing special here } elsif ($inprojref) { # nothing special here } elsif ($inprepro) { # like NDEBUG;$(NoInherit));%(PreprocessorDefinitions) # or _DEBUG;$(NoInherit));%(PreprocessorDefinitions) } elsif ($inrescomp) { # compiling a rc file } elsif ($inexcl) { # get/set if excluded } elsif ($inobjfname) { # get/set object file, like [$(IntDir)alpha.2.obj] } elsif ($inoptim) { # ... } elsif ($inbasicrtc) { # ... } else { prgm_exit(1,"ERROR: $lnn: ItemGroup type NOT HANDLED! [$tag]\n"); } } } else { if ($rtag eq '/ClCompile') { # just close of a compile, where there are properties added # # a CLOSED ClCompile # # an OPEN ClCompile # $(IntDir)alpha.2.obj # $(IntDir)alpha.2.obj # } else { $wmsg = "ItemGroup: NOT in conf [$rtag]"; if (!defined $shown_warn{$wmsg}) { prtw("WARNING: $lnn: $wmsg [$txt] FIX ME! 8\n file [$inff]\n"); $shown_warn{$wmsg} = 1; } } } } } } # 2 - PropertyGroup } elsif ($inpropgroup) { if ($tag =~ /^<\/PropertyGroup>/) { prt("$lnn:[v9]: End PropertyGroup\n") if (VERB9()); $inpropgroup = 0; } else { # # <_ProjectFileVersion>10.0.20506.1 # C:\FG\10\flightgear\build\src\FDM\YASim\Debug\ # yasim-proptest.dir\Debug\ # yasim-proptest # .exe # true # true # C:\FG\10\flightgear\build\src\FDM\YASim\Release\ # yasim-proptest.dir\Release\ # yasim-proptest # .exe # false # true # # # {DADB5FFC-3724-4318-BC6E-1DE2291A71F2} # Win32Proj # Win32 # yasim-proptest # $show = 0; if ($rtag =~ /^\//) { # on CLOSING tag, get TEXT if ($pglabel eq 'Globals') { if (($rtag eq '/ProjectGUID')||($rtag eq '/ProjectGuid')) { $show = 1; } elsif ($rtag eq '/Keyword') { $show = 1; } elsif ($rtag eq '/Platform') { $show = 1; } elsif ($rtag eq '/ProjectName') { ${$rh}{'PROJECT_NAME'} = $txt; $show = 1; } elsif ($rtag eq '/RootNamespace') { $show = 1; $RootNamespace = $txt; } elsif ($rtag eq '/WindowsTargetPlatformVersion') { # '/WindowsTargetPlatformVersion' $show = 1; } elsif ($rtag eq '/VCProjectUpgraderObjectName') { $show = 1; } } else { if ($rtag eq '/_ProjectFileVersion') { $show = 1; } elsif ($rtag eq '/OutDir') { # -NEW_OUTD- ${$rh}{'CURR_ODIR'} = $txt; $dsp_sub_sub = ${$rh}{'CURR_DSUB'}; if (defined ${$dsp_sub_sub}{'-NEW_OUTD-'}) { ${$dsp_sub_sub}{'-NEW_OUTD-'} = add_quotes($txt) if (length($txt)); } else { prtw("WARNING: current \$dsp_sub_sub does not have '-NEW_OUTD-'!\n"); } $show = 1; } elsif ($rtag eq '/IntDir') { # -NEW_INTER- $dsp_sub_sub = ${$rh}{'CURR_DSUB'}; if (defined ${$dsp_sub_sub}{'-NEW_INTER-'}) { ${$dsp_sub_sub}{'-NEW_INTER-'} = add_quotes($txt) if (length($txt)); } else { prtw("WARNING: current \$dsp_sub_sub does not have '-NEW_INTER-'!\n"); } $show = 1; } elsif ($rtag eq '/TargetName') { ${$rh}{'CURR_TNAME'} = $txt; $show = 1; } elsif ($rtag eq '/TargetExt') { # adds a BIG clue to the project TYPE # dll = DLL # lib = LIB (static) # exe = console or windows type ${$rh}{'CURR_TEXT'} = $txt; $show = 1; } elsif ($rtag eq '/LinkIncremental') { $show = 1; } elsif ($rtag eq '/GenerateManifest') { $show = 1; } elsif ($rtag eq '/CharacterSet') { $show = 1; } elsif ($rtag eq '/ConfigurationType') { set_configuration_type($rh,$txt); $show = 1; } elsif ($rtag eq '/UseOfMfc') { $show = 1; } elsif ($rtag eq '/WholeProgramOptimization') { $show = 1; } elsif ($rtag eq '/IgnoreImportLibrary') { $show = 1; } elsif ($rtag eq '/CodeAnalysisRuleSet') { $show = 1; } elsif ($rtag eq '/PlatformToolset') { $show = 1; #} elsif ($rtag eq '/...') { # $show = 1; } } if ($show) { $val = substr($rtag,1); prt("[v9] $lnn: Property: $pglabel: $val = [$txt], cond pg [$pgcond] oc [$opcond]\n") if (VERB9() || $dbg_07); } elsif ($rtag =~ /^\//) { prtw("WARNING: $lnn: $pglabel: Unmanaged PropertyGroup [$rtag] [$txt]\n file [$inff]\n"); } if (defined ${$rh}{'CURR_ODIR'} && defined ${$rh}{'CURR_TNAME'} && defined ${$rh}{'CURR_TEXT'}) { if (length(${$rh}{'CURR_ODIR'}) && length(${$rh}{'CURR_TNAME'}) && length(${$rh}{'CURR_TEXT'}) ) { $tmp = ${$rh}{'CURR_ODIR'}; $tmp .= $PATH_SEP if (!($tmp =~ /(\\|\/)$/)); $tmp .= ${$rh}{'CURR_TNAME'}; $tmp .= ${$rh}{'CURR_TEXT'}; $conf = ${$rh}{'CURR_CFG'}; $dsp_sub_sub = ${$rh}{'CURR_DSUB'}; ${$dsp_sub_sub}{'-NEW_OUT-'} = $tmp; prt("[v5] SET: -NEW_OUT-: cfg [$conf] with [$tmp]\n") if (VERB5()); } } } } } elsif ($idefgroup) { if ($tag =~ /<\/ItemDefinitionGroup>/) { $idefgroup = 0; prt("$lnn:[v9]: End ItemDefinitionGroup\n") if (VERB9()); $idopntag = ''; # clear the OPEN tag group } elsif ($tag =~ /^ # # /Zm1000 %(AdditionalOptions) # C:/FG/10/3rdparty/include;C:/FG/10/Boost-1.49;C:/FG/10/3rdparty/3rdParty/include;C:/FG/10/flightgear/src;C:/FG/10/flightgear/build/src;C:/FG/10/flightgear/build/src/Include;C:/FG/10/flightgear;%(AdditionalIncludeDirectories) # EnableFastChecks # CompileAsCpp # ProgramDatabase # Sync # Disabled # Disabled # MultiThreadedDebugDLL # true # Level3 # WIN32;_WINDOWS;NOMINMAX;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;__CRT_NONSTDC_NO_WARNINGS;_REENTRANT;_DEBUG;HAVE_CONFIG_H;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions) # Debug # $(IntDir) # C:/FG/10/flightgear/build/src/FDM/YASim/Debug/yasim-proptest.pdb # # # WIN32;_WINDOWS;NOMINMAX;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;__CRT_NONSTDC_NO_WARNINGS;_REENTRANT;_DEBUG;HAVE_CONFIG_H;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions) # C:/FG/10/3rdparty/include;C:/FG/10/Boost-1.49;C:/FG/10/3rdparty/3rdParty/include;C:/FG/10/flightgear/src;C:/FG/10/flightgear/build/src;C:/FG/10/flightgear/build/src/Include;C:/FG/10/flightgear;%(AdditionalIncludeDirectories) # # # C:/FG/10/3rdparty/include;C:/FG/10/Boost-1.49;C:/FG/10/3rdparty/3rdParty/include;C:/FG/10/flightgear/src;C:/FG/10/flightgear/build/src;C:/FG/10/flightgear/build/src/Include;C:/FG/10/flightgear;%(AdditionalIncludeDirectories) # $(IntDir) # %(Filename).h # %(Filename).tlb # %(Filename)_i.c # %(Filename)_p.c # # # /machine:X86 /debug %(AdditionalOptions) # kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;C:\FG\10\3rdparty\lib\sgenvironmentd.lib;C:\FG\10\3rdparty\lib\sgnasald.lib;C:\FG\10\3rdparty\lib\sgtsyncd.lib;C:\FG\10\3rdparty\lib\sgbucketd.lib;C:\FG\10\3rdparty\lib\sgrouted.lib;C:\FG\10\3rdparty\lib\sgiod.lib;C:\FG\10\3rdparty\lib\sgseriald.lib;C:\FG\10\3rdparty\lib\sgmathd.lib;C:\FG\10\3rdparty\lib\sgpropsd.lib;C:\FG\10\3rdparty\lib\sgstructured.lib;C:\FG\10\3rdparty\lib\sgtimingd.lib;C:\FG\10\3rdparty\lib\sgxmld.lib;C:\FG\10\3rdparty\lib\sgmiscd.lib;C:\FG\10\3rdparty\lib\sgthreadsd.lib;C:\FG\10\3rdparty\lib\sgdebugd.lib;C:\FG\10\3rdparty\lib\sgmagvard.lib;C:\FG\10\3rdparty\lib\zlib1.lib;winmm.lib;ws2_32.lib # %(AdditionalLibraryDirectories) # MultiplyDefinedSymbolOnly # true # C:/FG/10/flightgear/build/src/FDM/YASim/Debug/yasim-proptest.lib # true # C:/FG/10/flightgear/build/src/FDM/YASim/Debug/yasim-proptest.pdb # 10000000 # Console # # # # false # # # # setlocal #"C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -DBUILD_TYPE=$(Configuration) -P cmake_install.cmake #if %errorlevel% neq 0 goto :cmEnd #:cmEnd #endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone #:cmErrorLevel #exit /b %1 #:cmDone #if %errorlevel% neq 0 goto :VCEnd # # if ($tagtype == 1) { # a close TAG $show = 0; if ($nxtstag eq 'ClCompile') { if ($rtag eq '/AdditionalOptions') { $show = 1; } elsif ($rtag eq '/AdditionalIncludeDirectories') { # $seek = 'AdditionalIncludeDirectories'; # -NEW_INCS_[DBG|REL]- # sub get_default_sub3(0=rel,1=debug) { merge_inc_directories($rh,$txt); $show = 1; } elsif ($rtag eq '/BasicRuntimeChecks') { $show = 1; } elsif ($rtag eq '/CompileAs') { $show = 1; } elsif ($rtag eq '/DebugInformationFormat') { $show = 1; } elsif ($rtag eq '/ExceptionHandling') { $show = 1; } elsif ($rtag eq '/InlineFunctionExpansion') { $show = 1; } elsif ($rtag eq '/Optimization') { $show = 1; } elsif ($rtag eq '/RuntimeLibrary') { # 92: ItemDef: ClCompile: RuntimeLibrary = [MultiThreadedDebugDLL], cond idg [CONFIG=Debug|Win32] op [] -NEW_RT- set_runtime_library($rh,$txt); $show = 1; } elsif ($rtag eq '/RuntimeTypeInfo') { $show = 1; } elsif ($rtag eq '/WarningLevel') { $show = 1; } elsif ($rtag eq '/PreprocessorDefinitions') { # 94: ItemDef: ClCompile: PreprocessorDefinitions = [WIN32;_WINDOWS;_DEBUG;PNG_CONFIGURE_LIBPNG;_CRT_SECURE_NO_DEPRECATE;CMAKE_INTDIR="Debug";PNG_BUILD_DLL;%(PreprocessorDefinitions)], cond idg [CONFIG=Debug|Win32] op [] -NEW_DEFS- set_preprocessor_defines($rh,$txt); $show = 1; } elsif ($rtag eq '/AssemblerListingLocation') { $show = 1; } elsif ($rtag eq '/ObjectFileName') { $show = 1; } elsif ($rtag eq '/ProgramDataBaseFileName') { $show = 1; } elsif ($rtag eq '/FunctionLevelLinking') { # false $show = 1; } elsif ($rtag eq '/SuppressStartupBanner') { $show = 1; } elsif ($rtag eq '/MinimalRebuild') { $show = 1; } elsif ($rtag eq '/PrecompiledHeaderOutputFile') { $show = 1; } elsif ($rtag eq '/PrecompiledHeader') { $show = 1; } elsif ($rtag eq '/StringPooling') { $show = 1; } elsif ($rtag eq '/DisableSpecificWarnings') { # like 4996;4013;4018;4024;4047;4244 $show = 1; } elsif ($rtag eq '/BufferSecurityCheck') { $show = 1; } elsif ($rtag eq '/TreatWChar_tAsBuiltInType') { $show = 1; } elsif ($rtag eq '/ForceConformanceInForLoopScope') { $show = 1; } elsif ($rtag eq '/IntrinsicFunctions') { $show = 1; } elsif ($rtag eq '/FavorSizeOrSpeed') { $show = 1; } elsif ($rtag eq '/OmitFramePointers') { $show = 1; } elsif ($rtag eq '/PreprocessToFile') { $show = 1; } elsif ($rtag eq '/PreprocessSuppressLineNumbers') { $show = 1; } elsif ($rtag eq '/PreprocessKeepComments') { $show = 1; } elsif ($rtag eq '/BrowseInformation') { $show = 1; } elsif ($rtag eq '/ForcedIncludeFiles') { $show = 1; } elsif ($rtag eq '/OpenMPSupport') { $show = 1; } elsif ($rtag eq '/PrecompiledHeaderFile') { $show = 1; } elsif ($rtag eq '/UseUnicodeForAssemblerListing') { $show = 1; } elsif ($rtag eq '/WholeProgramOptimization') { $show = 1; } elsif ($rtag eq '/MultiProcessorCompilation') { $show = 1; } elsif ($rtag eq '/StructMemberAlignment') { $show = 1; } else { $wmsg = "Uncased 'ClCompile' [$tag]"; if (!defined $shown_warn{$wmsg}) { prtw("WARNING: $lnn: $wmsg FIX ME! 1\n"); $shown_warn{$wmsg} = 1; } } } elsif ($nxtstag eq 'ResourceCompile') { if ($rtag eq '/PreprocessorDefinitions') { # _DEBUG;%(PreprocessorDefinitions) $show = 1; } elsif ($rtag eq '/AdditionalIncludeDirectories') { $show = 1; } elsif ($rtag eq '/Culture') { # 0x0809 $show = 1; } else { prtw("WARNING: $lnn: Uncased 'ResourceCompile' [$tag] FIX ME! 9\n"); } } elsif ($nxtstag eq 'Midl') { if ($rtag eq '/AdditionalIncludeDirectories') { $show = 1; } elsif ($rtag eq '/OutputDirectory') { $show = 1; } elsif ($rtag eq '/HeaderFileName') { $show = 1; } elsif ($rtag eq '/TypeLibraryName') { $show = 1; } elsif ($rtag eq '/InterfaceIdentifierFileName') { $show = 1; } elsif ($rtag eq '/ProxyFileName') { $show = 1; } elsif ($rtag eq '/SuppressStartupBanner') { $show = 1; } elsif ($rtag eq '/PreprocessorDefinitions') { $show = 1; } elsif ($rtag eq '/MkTypLibCompatible') { $show = 1; } elsif ($rtag eq '/TargetEnvironment') { $show = 1; } else { prtw("WARNING: $lnn: Uncased 'Midl' [$tag] FIX ME! 10\n"); } } elsif ($nxtstag eq 'Link') { if ($rtag eq '/AdditionalOptions') { $show = 1; } elsif ($rtag eq '/AdditionalDependencies') { # like elsif ($pname eq 'VCLinkerTool') $var1 = '-NEW_LIBS-'; # get the list, and add need libraries # kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;C:\FG\10\3rdparty\lib\sgenvironmentd.lib;C:\FG\10\3rdparty\lib\sgnasald.lib;C:\FG\10\3rdparty\lib\sgtsyncd.lib;C:\FG\10\3rdparty\lib\sgbucketd.lib;C:\FG\10\3rdparty\lib\sgrouted.lib;C:\FG\10\3rdparty\lib\sgiod.lib;C:\FG\10\3rdparty\lib\sgseriald.lib;C:\FG\10\3rdparty\lib\sgmathd.lib;C:\FG\10\3rdparty\lib\sgpropsd.lib;C:\FG\10\3rdparty\lib\sgstructured.lib;C:\FG\10\3rdparty\lib\sgtimingd.lib;C:\FG\10\3rdparty\lib\sgxmld.lib;C:\FG\10\3rdparty\lib\sgmiscd.lib;C:\FG\10\3rdparty\lib\sgthreadsd.lib;C:\FG\10\3rdparty\lib\sgdebugd.lib;C:\FG\10\3rdparty\lib\sgmagvard.lib;C:\FG\10\3rdparty\lib\zlib1.lib;winmm.lib;ws2_32.lib @arr = split(";",$txt); my %liblist = (); my %dirs = (); foreach $tmp (@arr) { if ($tmp =~ /\.lib$/i) { my ($n,$d) = fileparse($tmp); $d = '' if ($d =~ /^\.(\\|\/)$/); if (is_system_lib($n)) { # we know about these } else { $liblist{$n} = 1; $dirs{$d} = 1 if (length($d)); } } elsif ($tmp =~ /\.res$/i) { # a RESOURCE file dependency } elsif ($tmp eq '%(AdditionalDependencies)') { # ignore this } elsif ($tmp eq '/MACHINE:X86') { # 20140103 ignore this } else { prtw("WARNING: $lnn: AdditionalDependencies: This is NOT .lib WHAT is IT? [$tmp]\n"); } } @arr = sort keys(%liblist); $tmp = scalar @arr; $val = (@arr) ? join(" ",@arr) : ''; if (@arr && VERB5()) { prt("[v5] $lnn: LIBRARIES: AdditionalDependencies: Got $tmp additional libraries [$val]\n"); } @arr = keys %dirs; $tmp =scalar @arr; if (@arr && VERB5()) { prt("[v5] $lnn: LIBDIRS: AdditionalDependencies: In $tmp dirs [".join(" ",@arr)."]\n"); } ${$rh}{'CURR_LIBS'} = \%liblist; ${$rh}{'CURR_LDIRS'} = \%dirs; merge_library_list($rh); $show = 1; } elsif ($rtag eq '/AdditionalLibraryDirectories') { $show = 1; } elsif ($rtag eq '/ForceFileOutput') { $show = 1; } elsif ($rtag eq '/GenerateDebugInformation') { $show = 1; } elsif ($rtag eq '/ImportLibrary') { $show = 1; } elsif ($rtag eq '/LinkIncremental') { $show = 1; } elsif ($rtag eq '/ProgramDataBaseFileName') { $show = 1; } elsif ($rtag eq '/StackReserveSize') { $show = 1; } elsif ($rtag eq '/SubSystem') { if ($txt =~ /Console/i) { if (defined ${$rh}{'PROJECT_APTP'}) { $val = ${$rh}{'PROJECT_APTP'}; if ($val eq 'Application') { ${$rh}{'PROJECT_APTP'} = 'Console Application'; prt("$lnn: SubSystem: Console: Changes App Type to 'Console Application'\n"); } } else { ${$rh}{'PROJECT_APTP'} = 'Console Application'; } } elsif ($txt =~ /Windows/i) { if (defined ${$rh}{'PROJECT_APTP'}) { $val = ${$rh}{'PROJECT_APTP'}; if ($val ne 'Application') { ${$rh}{'PROJECT_APTP'} = 'Application'; prt("$lnn: SubSystem: Windows: Changes App Type from [$val] to 'Application'\n"); } } else { ${$rh}{'PROJECT_APTP'} = 'Application'; } } else { prtw("WARNING: $lnn: 'SubSystem' NOT 'Console'! IS [$txt]! FIX ME! 11\n"); } $show = 1; } elsif ($rtag eq '/Version') { $show = 1; } elsif ($rtag eq '/SuppressStartupBanner') { $show = 1; } elsif ($rtag eq '/OutputFile') { $show = 1; } elsif ($rtag eq '/ModuleDefinitionFile') { $show = 1; } elsif ($rtag eq '/TargetMachine') { $show = 1; } elsif ($rtag eq '/OptimizeReferences') { $show = 1; } elsif ($rtag eq '/EnableCOMDATFolding') { $show = 1; } elsif ($rtag eq '/ProgramDatabaseFile') { $show = 1; } elsif ($rtag eq '/IgnoreSpecificDefaultLibraries') { $show = 1; } elsif ($rtag eq '/LinkDLL') { $show = 1; } elsif ($rtag eq '/BaseAddress') { $show = 1; } elsif ($rtag eq '/RandomizedBaseAddress') { $show = 1; } elsif ($rtag eq '/DataExecutionPrevention') { $show = 1; } elsif ($rtag eq '/Profile') { $show = 1; } elsif ($rtag eq '/IgnoreEmbeddedIDL') { $show = 1; } elsif ($rtag eq '/ImageHasSafeExceptionHandlers') { $show = 1; } elsif ($rtag eq '/IgnoreAllDefaultLibraries') { $show = 1; } elsif ($rtag eq '/LinkTimeCodeGeneration') { $show = 1; } elsif ($rtag eq '/ProgramDataBaseFile') { $show = 1; } else { $wmsg = "Uncased 'Link' [$tag]"; if (!defined $shown_warn{$wmsg}) { prtw("WARNING: $lnn: $wmsg [$txt] FIX ME! 12\n"); $shown_warn{$wmsg} = 1; } } } elsif ($nxtstag eq 'ProjectReference') { if ($rtag eq '/LinkLibraryDependencies') { $show = 1; } else { prtw("WARNING: $lnn: Uncased 'ProjectReference' [$tag] FIX ME! 13\n"); } } elsif ($nxtstag eq 'ItemDefinitionGroup') { # close of group } elsif ($nxtstag eq 'PostBuildEvent') { # close a postbuildevent } elsif ($nxtstag eq 'Bscmake') { # true # .\Debug\test_static\test_static.bsc # } elsif ($nxtstag eq 'Lib') { # # true # .\Debug\test_static\test_static.lib # } elsif ($nxtstag eq 'Message') { # ??? } elsif ($nxtstag eq 'CustomBuildStep') { # ??? } elsif ($nxtstag eq 'PreBuildEvent') { # 20151113 ??? } else { prtw("WARNING: $lnn: ItemDefinitionGroup: Uncased Next [$nxtstag] curr tag [$tag] FIX ME! 14\n file [$inff]\n"); } if ($show) { $val = substr($rtag,1); prt("[v9] $lnn: ItemDef: nxt $nxtstag: $val = [$txt], cond idg [$idconf] op [$opcond]\n") if (VERB9() || $dbg_08); #} elsif ($rtag =~ /^\//) { # prtw("WARNING: $lnn: Unmanaged PropertyGroup [$rtag] [$txt]\n"); } } elsif ($tagtype == 2) { if (($nxtstag ne 'ItemDefinitionGroup') && ($nxtstag ne $idopntag)) { # #if ($ntag eq 'Command') { # like =~ /^/) { prt("$lnn:[v9]: End ImportGroup\n") if (VERB9()); $impgroup = 0; } } elsif (length($tag)) { if ($tag =~ /^setlocal # "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -HC:/FG/10/flightgear -BC:/FG/10/flightgear/build --check-stamp-file C:\FG\10\flightgear\build\src\FDM\YASim\CMakeFiles\generate.stamp # if %errorlevel% neq 0 goto :cmEnd $incommand = 1; prt("\n[10] $lnn:outsied ItemGroup: SETTING incommnd\n\n") if ($dbg_10); #prt("$lnn:[v9]: Start command\n") if (VERB9()); prtw("WARNING: $lnn: Start command OUTSIDE ItemGroup!\n"); # should NOT happen $command = ''; } elsif ($tag =~ /^ $itemlabel = get_rt_value($rh,'Label'); prt("$lnn:[v9]: Start ItemGroup $itemlabel\n") if (VERB9()); $initemgroup = 1; } elsif ($tag =~ /^$/) { prt("$lnn:[v9]: Comp PropertyGroup\n") if (VERB9()); } else { # # $pgcond = get_rt_value($rh,'Condition'); $pglabel = get_rt_value($rh,'Label'); prt("$lnn:[v9]: Start PropertyGroup [$pgcond] [$pglabel]\n") if (VERB9()); $inpropgroup = 1; ${$rh}{'CURR_ODIR'} = ''; ${$rh}{'CURR_TNAME'} = ''; ${$rh}{'CURR_TEXT'} = ''; } } elsif ($tag =~ /^$/) { $inproj = 0; prt("$lnn:[v9]: End project\n") if (VERB9()); } elsif (($tag =~ /^$/)) { # } else { prtw("WARNING:$lnn: Tag not handled: [$tag]\n"); } } } else { # if ($tag =~ /^ 1, 'PACKAGE' => 1, 'WIN32' => 1, 'WIN32_LEAN_AND_MEAN' => 1, '_CONSOLE' => 1, '_CRT_NONSTDC_NO_WARNINGS' => 1, '_CRT_SECURE_NO_WARNINGS' => 1, '_DEBUG' => 1, '_LIB' => 1, '_MBCS' => 1, # '_VISUALC_' => 1, '_WIN32' => 1, '_WINDOWS' => 1, '__CONSOLE__' => 1 ); # __WIN32__ # @arr = filter_defines_list(\@arr); sub filter_defines_list($) { my $ra = shift; # \@arr; my @arr = (); my %dupes = (); my ($def); my $excl = 0; my $dups = 0; my $cnt = scalar @{$ra}; foreach $def (@{$ra}) { if (defined $exclude_defines{$def}) { $excl++; } elsif (defined $dupes{$def}) { $dups++; } else { push(@arr,$def); $dupes{$def} = 1; } } my $rcnt = scalar @arr; prt("[v5] Of original $cnt, defines, excluded $excl, and dups $dups, with $rcnt remaining.\n") if (VERB5()); return @arr; } sub get_comm_part($$) { my ($d1,$d2) = @_; my @arr1 = split(/\//,$d1); my @arr2 = split(/\//,$d2); my $len1 = scalar @arr1; my $len2 = scalar @arr2; my $len = ($len1 < $len2) ? $len1 : $len2; my $c = ''; my ($i); for ($i = 0; $i < $len; $i++) { $d1 = $arr1[$i]; $d2 = $arr2[$i]; if ($d1 eq $d2) { $c .= '/' if (length($c)); $c .= $d1; } else { last; } } return $c; } sub get_common_path($$$) { my ($m_ras,$m_rah,$m_sd) = @_; my $comp = ''; my ($src,$ff,$n,$d,$rel,$mlen); foreach $src (@{$m_ras}) { $ff = File::Spec->rel2abs($m_sd.$src); ($n,$d) = fileparse($ff); $rel = get_relative_path4($d,$out_cmake_dir); $ff = $rel.$n; my $nsrc = path_d2u($ff); my ($nn,$nd) = fileparse($nsrc); $nd =~ s/\/$//; $mlen = length($comp); if ($mlen) { if ($comp ne $nd) { $comp = get_comm_part($comp,$nd); } } else { $comp = $nd; } } foreach $src (@{$m_rah}) { $ff = File::Spec->rel2abs($m_sd.$src); ($n,$d) = fileparse($ff); $rel = get_relative_path4($d,$out_cmake_dir); $ff = $rel.$n; my $nsrc = path_d2u($ff); my ($nn,$nd) = fileparse($nsrc); $nd =~ s/\/$//; $mlen = length($comp); if ($mlen) { if ($comp ne $nd) { $comp = get_comm_part($comp,$nd); } } else { $comp = $nd; } } return $comp; } sub try_another_cmake($) { my $rparams = shift; my $cnt = scalar @proj_hash_array; return 0 if ($cnt == 0); my ($rh2); my $cmake = ''; my ($var1,$var2,$var3,$rel,$ff,$n,$d,$src,$scnt,$tmp); my (@arr); my %inc_dirs = (); my %def_items = (); my $cmake_exe = ''; $cnt = 0; my $leader = ''; my $exe_cnt = 0; my $ecomm_path = ''; foreach $rh2 (@proj_hash_array) { my $rh = get_hash_results($rh2,0); my $rc_files = ${$rh}{'PROJECT_C_SOURCES'}; # = \@c_files; my $rh_files = ${$rh}{'PROJECT_H_SOURCES'}; # = \@h_files; my $ro_files = ${$rh}{'PROJECT_O_SOURCES'}; # = \@o_files; my $name = ${$rh}{'PROJECT_NAME'}; # = $name; my $sdir = ${$rh}{'PROJECT_SDIR'}; # = $sdir; my $type = ${$rh}{'PROJECT_TYPE'}; # = $type; my $rincs = ${$rh}{'PROJECT_INCS'}; # = \%inc_hash; my $rdefs = ${$rh}{'PROJECT_DEFS'}; # = \%def_hash; # get FILE counts # ============================= my $ccnt = scalar @{$rc_files}; my $hcnt = scalar @{$rh_files}; my $ocnt = scalar @{$ro_files}; # ============================= my $icnt = scalar keys(%{$rincs}); my $dcnt = scalar keys(%{$rdefs}); my $pn = $name; $rel = get_relative_path4($sdir,$out_cmake_dir); ut_fix_directory(\$sdir); prt("Project [$name], type [$type], $ccnt C/C++, $hcnt Hdrs, $ocnt Other, $icnt INCS, $dcnt DEFS\n"); prt("File dir [$sdir], out [$out_cmake_dir], rel = [$rel]\n"); $var1 = ''; $var2 = ''; $var3 = ''; if ($ccnt) { if (length($proj_name) == 0) { $proj_name = $name; ${$rparams}{'PROJECT_NAME_MASTER'} = $proj_name; } my $comm_path = get_common_path($rc_files,$rh_files,$sdir); foreach $src (keys %{$rincs}) { $ff = File::Spec->rel2abs($sdir.$src); ut_fix_directory(\$ff); $ff .= "temp.txt"; ($n,$d) = fileparse($ff); $rel = get_relative_path4($d,$out_cmake_dir); $rel = path_d2u($rel); #next if ($rel =~ /\$\{dir\}/); accumulate_incs(\%inc_dirs,$rel); } foreach $src (keys %{$rdefs}) { $def_items{$src} = 1; } $leader = "\n# Project [$name], type [$type], $ccnt C/C++, $hcnt Hdrs, $ocnt Other, $icnt INCS, $dcnt DEFS\n"; $leader .= "# File dir [$sdir], out [$out_cmake_dir], rel = [$rel]\n"; $var1 = "\${name}_SRCS"; $scnt = scalar @{$rc_files}; $leader .= "set(name $name)\n"; $leader .= "set(dir $comm_path)\n"; $leader .= "set( $var1"; # if GT 2 put on a NEW line $leader .= "\n" if ($scnt > 2); $tmp = ''; @arr = (); $comm_path =~ s/\//\\\//; foreach $src (sort @{$rc_files}) { $ff = File::Spec->rel2abs($sdir.$src); ($n,$d) = fileparse($ff); $rel = get_relative_path4($d,$out_cmake_dir); $ff = $rel.$n; $src = path_d2u($ff); $ecomm_path = escape_regex($comm_path); $src =~ s/$ecomm_path/\$\{dir\}/; if ($scnt > 2) { $tmp .= " $src\n"; } else { $tmp .= " $src"; # stay on SAME line for short list } push(@arr,$src); } if ($scnt > 2) { #$tmp =~ s/\n$/ \)\n/; $tmp .= " )\n"; } else { $tmp .= " )\n"; } $leader .= $tmp; if ($hcnt) { $var2 = "\${name}_HDRS"; $leader .= "set( $var2"; $leader .= "\n" if ($hcnt > 2); foreach $src (sort @{$rh_files}) { $ff = File::Spec->rel2abs($sdir.$src); ($n,$d) = fileparse($ff); $rel = get_relative_path4($d,$out_cmake_dir); $ff = $rel.$n; $rel =~ s/\/$//; accumulate_incs(\%inc_dirs,$rel); $src = path_d2u($ff); $ecomm_path = escape_regex($comm_path); $src =~ s/$ecomm_path/\$\{dir\}/; if ($hcnt > 2) { $leader .= " $src\n"; } else { $leader .= " $src"; } #accumulate_incs(\%inc_dirs,$src); } if ($hcnt > 2) { $leader =~ s/\n$/ )\n/; } else { $leader .= " )\n"; } } if ($ocnt) { $var3 = $name."_OTHERS"; $leader .= "set( $var3\n"; foreach $src (sort @{$ro_files}) { $ff = File::Spec->rel2abs($sdir.$src); ($n,$d) = fileparse($ff); $rel = get_relative_path4($d,$out_cmake_dir); $ff = $rel.$n; $src = path_d2u($ff); $leader .= " $src\n"; } $leader =~ s/\n$/ )\n/; } if (($type eq 'Dynamic-Link Library') || ($type eq 'Static Library')) { $cmake .= $leader; $cmake .= "if (BUILD_ONE_LIBRARY)\n"; $cmake .= " list(APPEND lib_SOURCES \${$var1})\n"; # keep FULL SOURCE list $cmake .= " list(APPEND lib_HEADERS \${$var2})\n" if (length($var2)); # and HEADERS $cmake .= "else ()\n"; $cmake .= " add_library( \${name} "; if ($use_lib_option_var) { $cmake .= '${LIB_TYPE}'; } else { if ($type eq 'Dynamic-Link Library') { $cmake .= 'SHARED'; } else { $cmake .= 'STATIC'; } } ###$cmake .= "\n"; $cmake .= " \${$var1}"; if (length($var2)) { $cmake .= " \${$var2}"; } ###$cmake =~ s/\n$//; $cmake .= " )\n"; $cmake .= " list(APPEND add_LIBS \${name})\n"; # add to LINK libraries $cmake .= "endif ()\n"; } else { $exe_cnt++; $cmake_exe .= $leader; $cmake_exe .= "add_executable( \${name}"; $cmake_exe .= " \${$var1}"; if (length($var2)) { $cmake_exe .= " \${$var2}"; } $cmake_exe .= " )\n"; $cmake_exe .= "target_Link_libraries(\${name} \${add_LIBS} )\n"; $cmake_exe .= "if (MSVC)\n"; $cmake_exe .= " set_target_properties(\${name} PROPERTIES DEBUG_POSTFIX d )\n"; $cmake_exe .= "endif ()\n"; } $cnt++; } } $cmake .= "if (BUILD_ONE_LIBRARY)\n"; $cmake .= " add_library( $proj_name \${LIB_TYPE}"; $cmake .= " \${lib_SOURCES} \${lib_HEADERS} "; $cmake .= " )\n"; $cmake .= " list(APPEND add_LIBS $proj_name)\n"; # add to LINK libraries $cmake .= "endif ()\n"; # ==================================== # add executables AFTER libraries if (length($cmake_exe)) { $cmake .= "\n### $exe_cnt executables #############################################\n"; $cmake .= $cmake_exe; } # ==================================== @arr = sort keys %inc_dirs; $var2 = scalar @arr; if ($var2) { $var1 = "# Add $var2 include directories indicated\n"; # hmmm, why add 'SYSTEM' here - need to check meaning $var1 .= "include_directories( \n"; foreach $src (@arr) { $var1 .= " $src\n"; } $var1 =~ s/\n$//; $var1 .= " )\n\n"; $cmake = $var1.$cmake; } # 20140103 - Need to FILTER this list @arr = sort keys %def_items; $var1 = scalar @arr; @arr = filter_defines_list(\@arr); $var2 = scalar @arr; if ($var2) { $var1 = "# Adding $var2 of $var1 defines indicated.\n"; $var1 .= "add_definitions( \n"; foreach $src (@arr) { $var1 .= " -D$src\n"; } $var1 =~ s/\n$//; $var1 .= " )\n\n"; $cmake = $var1.$cmake; } $var1 = "# CMakeLists.txt generated ".lu_get_YYYYMMDD_hhmmss(time())."\n"; $var1 .= "# by $pgmname from $in_file\n\n"; $var1 .= "# local CMake Scripts.\n"; $var1 .= "# set(CMAKE_MODULE_PATH \${CMAKE_SOURCE_DIR}/CMakeModules )\n\n"; $var1 .= "cmake_minimum_required (VERSION 2.8.8)\n\n"; $var1 .= "project ($proj_name)\n\n"; # add usual header blob $var1 .= get_cmake_blob(); if ($add_3rdparty_stuff) { $var1 .= get_cmake_blob2(); } $cmake .= "\n# deal with install, if required\n"; $cmake .= "# install(TARGETS \${inst_LIBS}\n"; $cmake .= "# RUNTIME DESTINATION bin\n"; $cmake .= "# LIBRARY DESTINATION lib\n"; $cmake .= "# ARCHIVE DESTINATION lib )\n"; $cmake .= "# install(TARGETS \${inst_BINS} DESTINATION bin)\n"; $cmake .= "# install(FILES \${inst_HDRS} DESTINATION include)\n"; $cmake = $var1.$cmake."\n# eof\n"; $ff = $out_cmake_dir; ut_fix_directory(\$ff); $ff .= "CMakeLists.txt"; rename_2_old_bak($ff) if (-f $ff); write2file($cmake,$ff); prt("cmake output written to [$ff]\n"); return $cnt; } sub write_cmake_output() { if (get_write_cmake_files()) { if (!defined ${$rparams}{'AM_EXCLUDED_DIRS'}) { my %excluded = (); my $rex = \%excluded; ${$rparams}{'AM_EXCLUDED_DIRS'} = $rex; } #my $rparams = get_ref_params(); # need to set # my $rex = ${$rparams}{'AM_EXCLUDED_DIRS'}; # get stored EXCLUDED directory HASH (if any!) # my $proj_root = ${$rparams}{'ROOT_FOLDER'}; # my $proj_title = ${$rparams}{'PROJECT_NAME_MASTER'}; # my $rprojsh = ${$rparams}{'REF_PROJECTS_HASH'}; # my $rlib_lists = ${$rparams}{'REF_LIB_LISTS'}; # make list of LIBRARIES written #if (write_project_cmake_files($rparams)) { if (!try_another_cmake($rparams)) { prt("Write CMAKE FAILED!\n"); } #} } else { prt("Write CMAKE is disabled! Use -cmake:dir to enable.\n"); } } # ========================================================== # MAIN ############################################################ my $args_ref = parse_args(@ARGV); prt("By $pgmname, Version: $vers, on ".lu_get_YYYYMMDD_hhmmss(time())."\n"); foreach $in_file (@{$args_ref}) { prt("[v9] Processing file [$in_file]...\n") if (VERB9()); if (is_vcxproj_ext($in_file)) { process_vcxproj_file($in_file, $out_dsp_dir); } elsif (is_vcproj_ext($in_file)) { process_vcproj_file($in_file, $out_dsp_dir); } elsif (is_sln_ext($in_file)) { my $rsh = sln_file_processing(0, $in_file, $out_dsp_dir); show_sln_results($rsh); if (@project_list) { my $out_dsw = $out_dsp_dir."\\temp.$pgmname.DSW"; # write_proj_DSW3( $out_dsp_dir."\\temp.$pgmname.DSW", \@project_list); # DEBUG: # $dbg & 128 = get_configs_array3() # prt("[dbg & 1] write_proj_DSW3: 'temp' DSP file [$odsp]\n") if ($g_write_dbg & 1); # prt("[dbg & 2] write_proj_DSW3: 'absolute' DSP file [$fdsp]\n") if ($g_write_dbg & 2); # $debug_dsw_write = 3; prt("\nDoing write_proj_DSW3 to [$out_dsw]. Debug=[3]\n"); write_proj_DSW3( $out_dsw, $rsh, $out_bat_file, 3); } } else { prtw( "WARNING: Unprocessed file extension! [$in_file]!\n" ); } } write_cmake_output(); pgm_exit(0,""); ########################################################## sub chk_arg { my ($arg, @av) = @_; fatal( "Invalid $arg - needs value ... -? for help ... aborting!\n" ) if !(@av); } sub need_arg { my ($a, @b) = @_; if (!@b) { prt( "Error: $a argument requires additional item! Try -?\n" ); pgm_exit(1,"COMMAND ERROR"); } } sub load_arg_file($$); sub load_arg_file($$) { my ($fil,$lev) = @_; if (! open INF, "<$fil") { pgm_exit(1,"ERROR: Unable to open file [$fil]!\n"); } my @lines = ; close INF; my ($line,@arr,$lncnt,$i,$tmp,$sarg); @arr = (); $lncnt = scalar @lines; for ($i = 0; $i < $lncnt; $i++) { $line = $lines[$i]; $line = trim_all($line); next if (length($line) == 0); if ($line =~ /^\s*\#\s*include\s+"(.+)"/) { $sarg = $1; if (-f $sarg) { prt("Loading #include [$sarg]...\n") if (VERB1()); load_arg_file($sarg,$lev+1); } else { pgm_exit(1,"ERROR: INCLUDE file #include \"$sarg\" NOT FOUND\n"); } next; } next if ($line =~ /^#/); while ($line =~ /\\$/) { # got continuation of this line $i++; $tmp = trim_all($lines[$i]); next if ($tmp =~ /^#/); last if (length($tmp) == 0); $line =~ s/\\$//; $line = trim_all($line); $line .= $tmp; #add this to the line } # store argument from file if ($line =~ /\s/) { my @a = space_split($line); foreach $tmp (@a) { push(@arr,$tmp); } } else { push(@arr,$line); } } if (@arr) { $in_input_file++; parse_args(@arr); $in_input_file--; } } sub has_wild_cards($) { my $fil = shift; return 1 if ($fil =~ /(\?|\*)/); return 0; } sub first_colon_split($) { my $txt = shift; my $ind = index( $txt, ':'); my @arr = (); prt("[v9] Splitting on first colon [$txt]\n") if VERB9(); if ($ind > 2) { my ($tmp); $tmp = substr($txt,0,$ind); push(@arr, $tmp); prt("[v9] Added [$tmp]\n") if (VERB9()); $tmp = substr($txt,$ind+1); push(@arr, $tmp); prt("[v9] Added [$tmp]\n") if (VERB9()); } else { prt("[v9] No colon found!\n") if (VERB9()); push(@arr,$txt); } return @arr; } # watch out for -cmake:out;C:\..." sub set_cmake_options($) { my $sarg = shift; $write_cmake = 1; # 20161123 - Restore this my @arr = split(":",$sarg); ###my @arr = first_colon_split($sarg); my $cnt = scalar @arr; my ($i,$opt,@arr2,$msg); $msg = ''; # NOTE:1: skipping 'cmake:' for ($i = 1; $i < $cnt; $i++) { $opt = $arr[$i]; $msg = "Option: " if (length($msg) == 0); if (($opt eq '?')||($opt =~ /help/i)) { show_cmake_help(); pgm_exit(0,"cmake HELP exit(0)\n"); } elsif ($opt =~ /^it;.+/) { $opt =~ s/^it;//; $inst_hdr_path = $opt; $msg .= "Inst. hdrs to [$opt] "; } elsif ($opt =~ /^lt;.+/) { $opt =~ s/^lt;//; $inst_lib_path = $opt; $msg .= "Inst. libs to [$opt] "; } elsif ($opt =~ /^bt;.+/) { $opt =~ s/^bt;//; $inst_bin_path = $opt; $msg .= "Inst. bins to [$opt] "; } elsif ($opt =~ /^out;.+/) { $opt =~ s/^out;//; $out_cmake_dir = File::Spec->rel2abs($opt); # $sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of input # prt( "Setting to output cmake to abs=[$sarg]\n" ) if (VERB1()); # $out_cmake_dir = $sarg; if (-d $out_cmake_dir) { $msg .= "Root dir to [$out_cmake_dir] "; } else { pgm_exit(1,"ERROR: Root dir [$out_cmake_dir] DOES NOT EXIST!\n"); } } else { pgm_exit(1,"ERROR: Unknown cmake option [$opt] arg=$sarg (1)\n"); } } prt("Set to write CMake files $msg.\n"); } sub parse_args { # @ARGV my (@av) = @_; my $dn = scalar @av; my ($arg,$tmp,$i,$sarg,$val,@arr); if ($dbg_sl_06) { prt( "[dbg01] parsing $dn arguments... " ); for ($i = 0; $i < $dn; $i++) { prt( "[".$av[$i]."]" ); } prt("\n"); } $dn = 0; my $had_frp = 0; my $first_in = ""; $got_par = 0; while (@av) { $dn++; $arg = $av[0]; prt( "[dbg01] $dn: $arg\n" ) if ($dbg_sl_06); if (substr($arg,0,1) eq '-') { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if (($sarg eq '?')||($sarg eq 'h')||($sarg eq '-help')) { give_help(); pgm_exit(0,"HELP_EXIT"); } elsif ($sarg =~ /^\@/) { $sarg = substr($sarg,1); load_arg_file($sarg,0); } elsif ($sarg =~ /^adj-inter$/) { $adj_inter = 1; prt("Set to adjust output and inter dirs to \"Release\\\" and \"Debug\\\"\n") if (VERB1()); } elsif ($sarg =~ /^adj-out$/) { $adj_out = 1; prt("Set to adjust output to \"bin\\[D].exe\" EXE and DLL and \"lib\\...\" libs.\n") if (VERB1()); } elsif ($sarg =~ /^adj-rt$/) { need_arg(@av); shift @av; $dn++; $sarg = $av[0]; if (($sarg eq 'D')||($sarg eq 'T')) { $adj_rt = $sarg; if ($sarg eq 'D') { $tmp = "D = /MD and /MDd"; } else { $tmp = "T = /MT and /MTd"; } prt("Set to adjust RUNTIME to $tmp, accordingly.\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Argument $arg can ONLY be follwed by 'D' or 'T'! NOT [$sarg].\n"); } } elsif ($sarg =~ /^del-ndl-all$/) { $del_ndl_all = 1; prt( "Set to delete /nodefaultlib:\"*...*\"...\n" ) if (VERB1()); } elsif ($sarg =~ /^del-dll-all$/) { $del_dll_all = 1; prt("Set to remove any DLL build if both DLL and static, or change to static is only DLL\n") if (VERB1()); } elsif ($sarg =~ /^del-spl-bld$/) { $del_spl_bld = 1; prt("Remove any Special Tool Build blocks from DSP\n") if (VERB1()); } elsif ($sarg =~ /^in=(.+)$/) { $in_file = $1; if (has_wild_cards($in_file)) { @arr = glob($in_file); prt("Potential inputs: ".join(" ",@arr)."\n") if (@arr); prt("ERROR: At present do not support wild card inputs like [$arg]\n"); pgm_exit(1,"but do support multiple file inputs...\n"); } if (-f $in_file) { prt( "Set in file to [$in_file] ...\n" ) if (VERB1()); push(@user_inputs,$in_file); $first_in = $in_file if (length($first_in)==0); if (!$got_par) { prt("Calling 'init_common_subs($in_file)' from -in=file\n") if (VERB5()); $rparams = init_common_subs($in_file); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written $got_par = 1; } } else { prt( "Current Work Directory = [$pwd]\n" ); mydie( "ERROR: Can NOT locate IN FILE [$in_file]! check name, location! aborting...\n" ); } } elsif ($arg eq '-l') { $load_log = 1; prt( "Set in load log at end...\n" ) if (VERB1()); } elsif ($arg eq '-in') { need_arg(@av); shift @av; $dn++; $arg = $av[0]; prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06); if (has_wild_cards($arg)) { @arr = glob($arg); prt("Potential inputs: ".join(" ",@arr)."\n") if (@arr); prt("ERROR: At present do not support wild card inputs like [$arg]\n"); pgm_exit(1,"but do support multiple file inputs...\n"); } #$in_file = $arg; $in_file = File::Spec->rel2abs($arg); # get ABSOLUTE path of input if (-f $in_file) { prt( "Set in file to [$in_file] ...\n" ) if (VERB1()); push(@user_inputs,$in_file); $first_in = $in_file if (length($first_in)==0); if (!$got_par) { prt("Calling 'init_common_subs($in_file)' from in file\n") if (VERB5()); $rparams = init_common_subs($in_file); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written $got_par = 1; } } else { prt( "Current Work Directory = [$pwd]\n" ); pgm_exit(1,"ERROR: Can NOT locate IN FILE [$in_file]! check name, location! aborting...\n" ); } } elsif ($arg eq '-cmp') { $comp_2_dsps = 1; prt("Set compare NEW and any OLD DSP file.\n") if (VERB1()); } elsif ($arg eq '-debug') { set_sl_debug_on(); svc_set_dbg_on(); $dbg4write = -1; # all write DEBUG on } elsif ($arg =~ /^-cmake/) { $sarg = substr($arg,1); set_cmake_options($sarg); $dn++; #} elsif ($sarg =~ /^cmake:(.+)$/) { # $tmp = $1; # $sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of input # prt( "Setting to output cmake to abs=[$sarg]\n" ) if (VERB1()); # $out_cmake_dir = $sarg; # $write_cmake = 1; } elsif ($arg eq '-dsp') { $dn++; prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06); $write_dsp = 1; $g_had_dsp = 1; prt( "Setting to output a DSP to [$out_dsp_dir]\n" ) if (VERB1()); } elsif ($sarg =~ /^dsp:(.+)$/) { $tmp = $1; $sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of input prt( "Setting output file to abs=[$sarg] ($tmp), from [$out_dsp_dir]...\n" ) if (VERB1()); #$out_dsp_dir = $tmp; $out_dsp_dir = $sarg; $write_dsp = 1; $g_had_dsp = 1; } elsif ($sarg =~ /^n/) { need_arg(@av); shift @av; $sarg = $av[0]; $proj_name = $sarg; } elsif ($sarg =~ /^o/) { need_arg(@av); shift @av; $sarg = $av[0]; $out_cmake_dir = File::Spec->rel2abs($sarg); $write_cmake = 1; if (-d $out_cmake_dir) { prt("Set cmake root dir to [$out_cmake_dir].\n"); } else { pgm_exit(1,"ERROR: Root dir [$out_cmake_dir] DOES NOT EXIST!\n"); } } elsif ($arg =~ /^-type=(CA|WA|DLL|SL)$/) { $tmp = $1; if ( get_app_type_4_short($tmp,\$curr_app_type) && length($curr_app_type) ) { prt( "Set proj type override to [$curr_app_type] ($tmp)...\n" ) if (VERB1()); } else { mydie( "ERROR: Unknown option [$arg] ... try -? ... aborting!\n" ); } } elsif (($arg eq '-fix-rel')||($arg eq '-fix_rel')) { $fix_rel_paths = 1; prt("Set to fix relative paths of sources.\n") if (VERB1()); $had_frp = 1; } elsif ($sarg =~ /^svc-dbg=(\d+)/) { $val = $1; prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06); if (svc_set_dbg_item($val,1)) { pgm_exit(1,"ERROR: Unable to set lib_vcscan.pl dbg_v$val... aborting!\n" ); } } elsif ($sarg =~ /^svc-dbg$/) { need_arg(@av); shift @av; $dn++; $sarg = $av[0]; prt("[dbg01] $dn: $arg $sarg\n") if ($dbg_sl_06 || VERB9()); if ( !($sarg =~ /^\d+$/) || ( svc_set_dbg_item($sarg,1) ) ) { pgm_exit(1,"ERROR: [$arg] [$sarg] Unable to set lib_vcscan.pl dbg_v$sarg... aborting!\n" ); } } elsif ($sarg =~ /^show-hash$/) { $dbg_sl_04 = 1; # Show DSP hash results (for debug). prt("Set to show DSP hash results (for debug).\n") if (VERB1()); } elsif ($sarg eq 'type') { need_arg(@av); shift @av; $dn++; $arg = $av[0]; prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06 || VERB9()); if ($arg =~ /^(CA|WA|DLL|SL)$/) { $tmp = $1; if ( get_app_type_4_short($tmp,\$curr_app_type) && length($curr_app_type) ) { prt( "Set proj type override to [$curr_app_type] ($tmp)...\n" ) if (VERB1()); } else { pgm_exit(1,"ERROR: Unknown option [-type $arg] ... try -? ... aborting!\n" ); } } else { pgm_exit(1,"ERROR: Unknown option [$arg]! Expected one {CA|WA|DLL|SL]!! try -? ... aborting!\n" ); } } elsif ($sarg =~ /^v/) { if ($sarg =~ /^v(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/) { $verbosity++; $sarg = substr($sarg,1); } } $dbg4write = -1 if (VERB9()); # all write DEBUG on prt("Set verbosity to [$verbosity]\n") if (VERB1()); } elsif ($arg eq '-ll') { $load_log = 1; prt("Set to load log at end.\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Unknown option [$arg] ... try -? ... aborting!\n" ); } } else { # bare item - assume an INPUT file #$in_file = $arg; if (has_wild_cards($arg)) { @arr = glob($arg); prt("Potential inputs: ".join(" ",@arr)."\n") if (@arr); prt("ERROR: At present do not support wild card inputs like [$arg]\n"); pgm_exit(1,"but do support multiple file inputs...\n"); } $in_file = File::Spec->rel2abs($arg); # get ABSOLUTE path of input if (-f $in_file) { # does this call 'set_params_ref'??? Looks like it DOES prt( "Set in file to [$in_file] ...\n" ) if (VERB1()); push(@user_inputs,$in_file); $first_in = $in_file if (length($first_in)==0); if (!$got_par) { prt("Calling 'init_common_subs($in_file)' from bare file\n") if (VERB5()); $rparams = init_common_subs($in_file); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written $got_par = 1; } } else { prt( "Current Work Directory = [$pwd]\n" ); pgm_exit(1,"ERROR: Can NOT locate IN FILE [$in_file]! check name, location! aborting...\n" ); } } shift @av; } if ($in_input_file) { return; } if ($had_frp && !$g_had_dsp) { pgm_exit(1,"ERROR: Option conflict! Had -fix_rel, but no -dsp= for output.\n"); } $dn = scalar @user_inputs; if (!$dn && $debug_on && length($def_in_file) && (-f $def_in_file) && length($def_out_dsp_dir) && (-d $def_out_dsp_dir)) { $in_file = $def_in_file; push(@user_inputs,$in_file); $out_dsp_dir = $def_out_dsp_dir; $fix_rel_paths = 1; #$load_log = 1; #$verbosity = 9; #$dbg4write = -1; prt("DEBUG ON: Set input to [$in_file], and out [$out_dsp_dir]\n"); $rparams = init_common_subs($in_file) if (!$got_par); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written $got_par = 1; $write_cmake = 1; } $dn = scalar @user_inputs; if ($dn) { prt("Got $dn items to process...\n"); } else { # no file(s), and not $debug_on ### give_help(); pgm_exit(1,"ERROR: No input file found!\n"); } if (length($out_dsp_dir) == 0) { pgm_exit(1,"ERROR: No DSP out directory givent! Aborting..."); } elsif (! -d $out_dsp_dir) { pgm_exit(1,"ERROR: DSP out directory [$out_dsp_dir] does NOT exist! Aborting..."); } if ($write_cmake) { #my $out_cmake_dir = ''; } if (length($first_in)) { if (defined $rparams) { if (! defined ${$rparams}{'PROJECT_AM_FILE'}) { ${$rparams}{'PROJECT_AM_FILE'} = $first_in; prt("Set rparams'PROJECT_AM_FILE' to [$first_in]\n") if (VERB5()); } else { prt("Note rparams['PROJECT_AM_FILE'] set to [".${$rparams}{'PROJECT_AM_FILE'}."]\n") if (VERB5()); } if (length($proj_name)) { ${$rparams}{'PROJECT_NAME_MASTER'} = $proj_name; } } else { prtw("WARNING: Appears 'rparams' NOT defined!\n"); } } return \@user_inputs; } # -cmp - If an existing DSP file, compare NEW and OLD. # -cmake[:dir] - Write cmake file to this root directory. Default to in file directory if none given. sub give_help { my $help = <" and "Debug\\" -adj-out - Adjust output to "bin\\.exe" and "bin\\D.exe" for EXE and DLL projects, and "lib\\.lib" and "lib\\D.lib" for libraries. -adj-rt - Adjust runtime, D = /MD and /MDd, T = /MT and /MTd, accordingly. -cmake[:opt] - Enable CMake output. See options below. -del-ndl-all - To delete /nodefaultlib:\"*...*\", if found -del-dll-all - Remove any DLL build if both DLL and static, or change to static is only DLL -del-spl-bld - Remove any Special Tool Build blocks from DSP -dsp[:dsp_dir] - Write DSP file(s) to this directory. (def=$out_dsp_dir). -in=in_file - Alternative to set input file. -ll - Load LOG at end. -fix-rel - Fix relative paths, if an output directory, relative to source, given. -svc-dbg= - Set this debug item in the lib_vcscan.pl module. -show-hash - Show DSP hash results (for debug \$dbg_v04). -type=TYPE - Override project type. TYPES = [CA|WA|DLL|SL] only. CA=Console App, WA=Windows App, DLL=Dynamic-Link, Lib SL=Static Library. -out (-o) - Set the CMakeLists.txt output directory. -name - Set project name.\ -v[n] - Bump (or set) verbosity. Def=$verbosity The 'input file' can be either a single 'vcproj' file, of a 'sln' file. If a solution file (*.sln) is given, then all the project files if contains (*.vcproj) will first be extracted, and then processed one-by-one. EOF prt( $help ); prt(" -cmake[:opt[:opt...]] = Enable CMakeLists.txt ouput, to out;dir, or -o .\n"); show_cmake_help(); } sub show_cmake_help { prt(" Can be followed by a list of colon separated special cmake options.\n"); prt(" it;targ = Set special 'install' headers option, like it;include/plib for PLIB.\n"); prt(" lt;targ = Set special 'install' libraries option, like lt;sbin for a system utility.\n"); prt(" bt;targ = Set special 'install' binary option, perhaps like bt;bin/tg.\n"); prt(" out;targ = Set target root output directory.\n"); prt(" Other otions to follow as they are identified.\n"); } # eof - vcproj05.pl