#!/usr/bin/perl -w # NAME: showsln.pl # AIM: Read a MSVC solution file, and details the project # 08/07/2020 - Review in Dell03, and some enhancement # 18/12/2013 - Adjust what is shown by 'verbosity' # 20/05/2013 - Works well ;=)) Time for some improvemments # 17/05/2013 geoff mclane http://geoffair.net/mperl use strict; use warnings; 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 use XML::Simple; use Data::Dumper; use Cwd; my $os = $^O; my $perl_dir = '/home/geoff/bin'; my $PATH_SEP = '/'; my $temp_dir = '/tmp'; if ($os =~ /win/i) { $perl_dir = 'C:\GTools\perl'; $temp_dir = $perl_dir; $PATH_SEP = "\\"; } unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n"; # log file stuff our ($LF); my $pgmname = $0; if ($pgmname =~ /(\\|\/)/) { my @tmpsp = split(/(\\|\/)/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt"; open_log($outfile); # user variables my $VERS = "0.0.2 2020-07-08"; #my $VERS = "0.0.1 2013-03-17"; my $load_log = 0; my $in_file = ''; my $verbosity = 0; my $out_file = ''; my $tmp_cmake_list = $temp_dir.$PATH_SEP."CMakeLists.txt"; my $del_opt_libs = 1; my $del_GL_libs = 1; my $del_dbg_libs = 1; my $del_special_cmake = 1; my $del_optional_defines = 1; my $rel_dir = ''; # ### DEBUG ### my $debug_on = 0; my $def_file = 'C:\FG\18\fltk-1.3.2\ide\VisualC2010\fltk.sln'; ##my $def_file = 'C:\FG\18\fltk-1.3.2\ide\VisualC2010\adjuster.vcxproj'; my $dbg_sl_01 = 0; my $dbg_sl_02 = 0; my $dbg_sl_03 = 0; my $dbg_sl_14 = 0; my $dbg_sl_15 = 0; my $dbg_sl_16 = 0; ### program variables my @warnings = (); my $cwd = cwd(); my ($g_name,$g_sln_path,$g_ext); # get the NAME, and SOLUTION PATH (should be ABSOLUTE, NOT relative) sub VERB1() { return $verbosity >= 1; } sub VERB2() { return $verbosity >= 2; } sub VERB5() { return $verbosity >= 5; } sub VERB9() { return $verbosity >= 9; } sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { prt( "\nNo warnings issued.\n\n" ) if (VERB9()); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_log($outfile,$load_log); exit($val); } sub prtw($) { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } 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 mycmp_nc_sort { return -1 if (lc($a) lt lc($b)); return 1 if (lc($a) gt lc($b)); return 0; } sub mycmp_nc_fn_only { my ($f1,$d1,$e1) = fileparse($a, qr/\.[^.]*/); my ($f2,$d2,$e2) = fileparse($b, qr/\.[^.]*/); return -1 if (lc($f1) lt lc($f2)); return 1 if (lc($f1) gt lc($f2)); 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; } my %Level_1 = ( 'ItemGroup' => 2, 'xmlns' => 1, 'Import' => 2, 'ImportGroup' => 2, 'PropertyGroup' => 2, 'DefaultTargets' => 1, 'ToolsVersion' => 1, 'ItemDefinitionGroup' => 2 ); my %ItemGourp = ( 'ProjectConfiguration' => 2, 'ClCompile' => 2, # arr of hash 'Include' => '..\\..\\test\\CubeMain.cxx' 'CustomBuild' => 2, 'ProjectReference' => 2 ); my %ItemDefinitionGroup = ( 'Midl' => 3, # 'HeaderFileName' => {}, 'TargetEnvironment' => 'Win32', 'TypeLibraryName' => '.\\CubeView__0/CubeView.tlb', # 'PreprocessorDefinitions' => '_DEBUG;%(PreprocessorDefinitions)' 'ResourceCompile' => 3, # 'Culture' => '0x0409', 'PreprocessorDefinitions' => '_DEBUG;%(PreprocessorDefinitions)' 'Condition' => 1, #'\'$(Configuration)|$(Platform)\'==\'Debug|Win32\'', 'Link' => 3, #'ProgramDatabaseFile' => '$(IntDir)$(TargetName).pdb', # 'GenerateDebugInformation' => 'true', # 'AdditionalDependencies' => 'opengl32.lib;comctl32.lib;%(AdditionalDependencies)', # 'TargetMachine' => 'MachineX86', # 'IgnoreSpecificDefaultLibraries' => 'libcd;%(IgnoreSpecificDefaultLibraries)', # 'SubSystem' => 'Windows', # 'DataExecutionPrevention' => {}, # 'RandomizedBaseAddress' => 'false', # 'SuppressStartupBanner' => 'true', # 'OutputFile' => '../../test/CubeViewd.exe', # 'AdditionalLibraryDirectories' => '..\\..\\lib;%(AdditionalLibraryDirectories)' 'ClCompile' => 3 # 'Optimization' => 'Disabled', # 'CompileAs' => 'Default', # 'DebugInformationFormat' => 'ProgramDatabase', # 'SuppressStartupBanner' => 'true', # 'PrecompiledHeader' => {}, # 'RuntimeLibrary' => 'MultiThreadedDebugDLL', #'PreprocessorDefinitions' => '_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN;%(PreprocessorDefinitions)', # 'AdditionalIncludeDirectories' => '.;..\\..\\zlib;..\\..\\png;..\\..\\jpeg;../..;%(AdditionalIncludeDirectories)' ); my %master_hash = (); # collect ALL information into here ######################################################################## ##### CMake Stuff my $libcmake = ''; my $execmake = ''; my $tot_libs = 0; my $tot_exes = 0; my $proj_title = 'temp'; my $ver_maj = 4; my $ver_min = 0; my $ver_pt = 0; my $ver_rc = ''; my $ver_msg = 'FIX ME'; my $tot_files = 0; my $tot_lines = 0; my $add_options = 0; # add options around each componets, -O my $opt_list = ''; my $add_static_runtime = 1; my %include_dirs = (); my @add_inc_dirs = (); sub add_options_block($) { my $type = shift; my $txt = < given!\n"); } rename_2_old_bak($out_file); write2file($cmake,$out_file); prt("CMake string written to [$out_file]\n"); } ######################################################################## sub process_xml_file($$$) { my ($inf,$proj,$num) = @_; if (! -f $inf ) { pgm_exit(1,"ERROR: Unable to find file [$inf]\n"); } if (! open INF, "<$inf") { pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); } my @lines = ; close INF; my $lncnt = scalar @lines; $tot_files++; $tot_lines += $lncnt; my $line = join("",@lines); my $xml = new XML::Simple; # (ForceArray => 0); my $data = $xml->XMLin($line); #my $data = $xml->XMLin($inf); ##prt(Dumper($data)); ##$load_log = 2; my ($key,$val,$typ,$acnt,$rt,$righ,@arr,$item,$tmp); my ($rcmpa); my ($rca,$src); my ($rpph,$ppc,$rppa,$ff); my %SOURCES = (); my %FF_SRCS = (); my %HEADERS = (); my %FF_HDRS = (); my @a = (); my %pp = (); my %aid = (); # 'AdditionalIncludeDirectories' my %ald = (); my %adl = (); my $config = ''; my $subsystem = ''; $ff = File::Spec->rel2abs($inf); my ($inam,$idir) = fileparse($ff); foreach $key (keys %Level_1) { $typ = $Level_1{$key}; if (defined ${$data}{$key}) { $val = ${$data}{$key}; $rt = ref($val); if ($typ == 1) { prt("$key = $val\n") if (VERB9()); } elsif ($typ == 2) { # this is an ARRAY if ($rt eq 'ARRAY') { $acnt = scalar @{$val}; prt("$key is arrays with $acnt members...\n") if (VERB9()); if ($key eq 'ItemGroup') { # this is where we SHOULD find the SOURCES foreach $righ (@{$val}) { if (defined ${$righ}{'ClCompile'}) { $rcmpa = ${$righ}{'ClCompile'}; $rt = ref($rcmpa); if ($rt eq 'ARRAY') { foreach $rca (@{$rcmpa}) { $item = 'Include'; if (defined ${$rca}{$item}) { $src = ${$rca}{$item}; $SOURCES{$src} = 1; $ff = File::Spec->rel2abs($idir.$src); $FF_SRCS{$ff} = 1; } $item = 'PreprocessorDefinitions'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(PreprocessorDefinitions\)//; $pp{$ppc} = 1 if (length($ppc)); } } } $item = 'AdditionalIncludeDirectories'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(AdditionalIncludeDirectories\)//; $aid{$ppc} = 1 if (length($ppc)); } } } } } elsif ($rt eq 'HASH') { $rca = $rcmpa; $item = 'Include'; if (defined ${$rca}{$item}) { $src = ${$rca}{$item}; $SOURCES{$src} = 1; $ff = File::Spec->rel2abs($idir.$src); $FF_SRCS{$ff} = 1; } $item = 'PreprocessorDefinitions'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(PreprocessorDefinitions\)//; $pp{$ppc} = 1 if (length($ppc)); } } } $item = 'AdditionalIncludeDirectories'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(AdditionalIncludeDirectories\)//; $aid{$ppc} = 1 if (length($ppc)); } } } } } elsif (defined ${$righ}{'ClInclude'}) { $rcmpa = ${$righ}{'ClInclude'}; $rt = ref($rcmpa); if ($rt eq 'ARRAY') { foreach $rca (@{$rcmpa}) { $item = 'Include'; if (defined ${$rca}{$item}) { $src = ${$rca}{$item}; $ff = File::Spec->rel2abs($idir.$src); $HEADERS{$src} = 1; if (-f $ff) { $FF_HDRS{$ff} = 1; } else { prtw("WARNING:[v9]: Failed to find '$ff`, '$src'\n") if (VERB9()); } } } } elsif ($rt eq 'HASH') { $rca = $rcmpa; $item = 'Include'; if (defined ${$rca}{$item}) { $src = ${$rca}{$item}; $HEADERS{$src} = 1; $ff = File::Spec->rel2abs($idir.$src); if (-f $ff) { $FF_HDRS{$ff} = 1; } else { prtw("WARNING:[v9]: Failed to find '$ff`, '$src'\n") if (VERB9()); } } } } } } elsif ($key eq 'ItemDefinitionGroup') { foreach $righ (@{$val}) { if (defined ${$righ}{'Link'}) { $rcmpa = ${$righ}{'Link'}; $rt = ref($rcmpa); if ($rt eq 'HASH') { foreach $rca (keys %{$rcmpa}) { $ppc = ${$rcmpa}{$rca}; if ($rca eq 'AdditionalDependencies') { $ppc =~ s/\%\(AdditionalDependencies\)//; @a = split(';',$ppc); foreach $ppc (@a) { $adl{$ppc} = 1 if (length($ppc)); } } elsif ($rca eq 'AdditionalLibraryDirectories') { $ppc =~ s/\%\(AdditionalLibraryDirectories\)//; @a = split(';',$ppc); foreach $ppc (@a) { $ald{$ppc} = 1 if (length($ppc)); } } elsif ($rca eq 'SubSystem') { $subsystem = $ppc if (length($ppc)); } } } } elsif (defined ${$righ}{'ClCompile'}) { $rcmpa = ${$righ}{'ClCompile'}; $rt = ref($rcmpa); if ($rt eq 'ARRAY') { foreach $rca (@{$rcmpa}) { $item = 'PreprocessorDefinitions'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(PreprocessorDefinitions\)//; $pp{$ppc} = 1 if (length($ppc)); } } } $item = 'AdditionalIncludeDirectories'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(AdditionalIncludeDirectories\)//; $aid{$ppc} = 1 if (length($ppc)); } } } } } elsif ($rt eq 'HASH') { $rca = $rcmpa; $item = 'PreprocessorDefinitions'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; $rt = ref($rppa); if ($rt eq 'ARRAY') { foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(PreprocessorDefinitions\)//; $pp{$ppc} = 1 if (length($ppc)); } } } elsif ($rt eq 'HASH') { $rpph = $rppa; if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(PreprocessorDefinitions\)//; $pp{$ppc} = 1 if (length($ppc)); } } elsif ($rt eq '') { $ppc = $rppa; $ppc =~ s/\%\(PreprocessorDefinitions\)//; $pp{$ppc} = 1 if (length($ppc)); } } $item = 'AdditionalIncludeDirectories'; if (defined ${$rca}{$item}) { $rppa = ${$rca}{$item}; $rt = ref($rppa); if ($rt eq 'ARRAY') { foreach $rpph (@{$rppa}) { if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(AdditionalIncludeDirectories\)//; $aid{$ppc} = 1 if (length($ppc)); } } } elsif ($rt eq 'HASH') { $rpph = $rppa; if (defined ${$rpph}{'content'}) { $ppc = ${$rpph}{'content'}; $ppc =~ s/\%\(AdditionalIncludeDirectories\)//; $aid{$ppc} = 1 if (length($ppc)); } } elsif ($rt eq '') { $ppc = $rppa; $ppc =~ s/\%\(AdditionalIncludeDirectories\)//; $aid{$ppc} = 1 if (length($ppc)); } } } } } } elsif ($key eq 'PropertyGroup') { $rt = ref($val); if ($rt eq 'ARRAY') { foreach $righ (@{$val}) { $rt = ref($righ); if ($rt eq 'HASH') { # Application, DynamicLibrary, StaticLibrary $item = 'ConfigurationType'; if (defined ${$righ}{$item}) { $ppc = ${$righ}{$item}; if (length($config)) { @a = split(';',$config); foreach $src (@a) { if ($src eq $ppc) { $ppc = ''; last; } } $config .= ";$ppc" if (length($ppc)); } else { $config = $ppc if (length($ppc)); } } } } } } } else { prt("$key: expected array, but got [$rt]\n"); } } } else { prt("Key $key not found in xml!\n"); } } my $splproj = 0; # ===================================================================== # show what was found in this file # A CONSOLE APP SHOWS: AppType: Application;Console # A WINDOWS APP SHOWS: AppType: Application;Windows # A SHARED DLL SHOWS: AppType: DynamicLibrary;Windows # A STATIC LIB SHOWS: AppType: StaticLibrary; if (($proj eq 'ALL_BUILD')||($proj eq 'INSTALL')||($proj eq 'ZERO_CHECK')) { prt("[v9]: $proj: AppType: $config;$subsystem\n") if (VERB9()); # if (length($config)||length($subsystem)); $splproj = 1; } else { prt("[v1]: $proj:$num: AppType: $config;$subsystem\n") if (VERB1()); # if (length($config)||length($subsystem)); } ##################################################### $master_hash{$proj}->{inputfile} = $inf; $master_hash{$proj}->{apptype} = "$config;$subsystem"; my ($relpath,%bs); my ($n,$d,$ext); # =================================================================== # DEAL with the SOURCES if any ############################## ###@a = sort mycmp_nc_fn_only keys(%SOURCES); @a = sort mycmp_nc_fn_only keys(%FF_SRCS); if (length($rel_dir)) { # need to get relative path to this directory %bs = (); foreach $key (@a) { $tmp = $key; ($n,$d) = fileparse($key); $relpath = get_rel_dos_path($d,$rel_dir); $key = $relpath.$n; prt("[v9]: $tmp -> $key\n") if (VERB9()); $bs{$key} = 1; } ### @a = sort mycmp_nc_fn_only keys(%bs); @a = sort mycmp_nc_sort keys(%bs); } $master_hash{$proj}->{sources} = [@a]; $tmp = scalar @a; if ($tmp) { prt("[v1]: $proj:$num: $tmp Sources:\n") if (VERB1()); prt("[v5]: ".join("\n",@a)."\n") if (VERB5()); } elsif (!$splproj) { prtw("WARNING: $proj:$num: No sources found.\n"); # if (VERB5()); } # DEAL with the HEADER if any ############################## ###@a = sort mycmp_nc_fn_only keys(%HEADERS); @a = sort mycmp_nc_fn_only keys(%FF_HDRS); if (length($rel_dir)) { # need to get relative path to this directory %bs = (); foreach $key (@a) { $tmp = $key; ($n,$d) = fileparse($key); $relpath = get_rel_dos_path($d,$rel_dir); $key = $relpath.$n; prt("[v9]: $tmp -> $key\n") if (VERB9()); $bs{$key} = 1; } ### @a = sort mycmp_nc_fn_only keys(%bs); @a = sort mycmp_nc_sort keys(%bs); } $master_hash{$proj}->{headers} = [@a]; $tmp = scalar @a; if ($tmp) { prt("$proj:$num: $tmp Headers:\n") if (VERB1()); prt(join("\n",@a)."\n") if (VERB5()); } elsif (!$splproj) { prtw("WARNING: $proj:$num: No headers found.\n") if (VERB5()); } # ==================================================================== # deal with PREPROCESSOR instruction - try to reduce to minimum #################################### # drop known items my %drop_outs = ( '_WINDOWS' => 1, '_DEBUG' => 1, 'NDEBUG' => 1, 'WIN32_LEAN_AND_MEAN' => 1, 'WIN32' => 1, 'WIN32_EXTRA_LEAN' => 1, 'VC_EXTRA_LEAN' => 1, '_CRT_SECURE_NO_DEPRECATE' => 1, '__CRT_NONSTDC_NO_WARNINGS' => 1, '_SCL_SECURE_NO_WARNINGS' => 1, '_CRT_SECURE_NO_WARNINGS' => 1 ); my %drop_optional = ( '_REENTRANT' => 1, # also maybe optional '_USE_MATH_DEFINES' => 1, # maybe should be optional 'NOMINMAX' => 1 ); @a = keys %pp; %pp = (); foreach $key (@a) { $key = trim_all($key); @arr = split(";",$key); foreach $key (@arr) { $key = trim_all($key); next if (defined $drop_outs{$key}); if (length($key)) { if ($del_special_cmake) { next if ($key =~ /^CMAKE_INTDIR=/); } if ($del_optional_defines) { next if (defined $drop_optional{$key}); } $pp{$key} = 1; } } } @a = sort keys %pp; $master_hash{$proj}->{preprocs} = [@a]; if (@a) { prt("$proj:$num: PreProcs: ".join(";",@a)."\n") if (VERB5()); } # ==================================================================== # ==================================================================== # LIKEWISE - remove all duplicates, sort, and ensure DOS ################################## @a = keys %aid; # 'AdditionalIncludeDirectories' %aid = (); foreach $key (@a) { $key = trim_all($key); next if (length($key) == 0); @arr = split(";",$key); foreach $key (@arr) { $key = trim_all($key); if (length($key)) { $key = path_u2d($key); $aid{$key} = 1; } } } @a = sort mycmp_nc_sort keys(%aid); # 'AdditionalIncludeDirectories' if (length($rel_dir)) { # need to get relative path to this directory %bs = (); foreach $key (@a) { $ff = File::Spec->rel2abs($idir.$key); $relpath = get_rel_dos_path($ff,$rel_dir); $relpath =~ s/\\$//; prt("[v9]:aid: $key -> $ff -> $relpath\n") if (VERB9()); $bs{$relpath} = 1; } ###@a = sort mycmp_nc_fn_only keys(%bs); @a = sort mycmp_nc_sort keys(%bs); } $master_hash{$proj}->{addincs} = [@a]; if (@a) { prt("[v2]: $proj:$num: AddIncs: ".join(";",@a)."\n") if (VERB2()); } # ==================================================================== # ==================================================================== # would like to DROP all standard windows libraries my %win_libraries = ( 'ole32.lib' => 1, 'shell32.lib' => 1, 'uuid.lib' => 1, 'kernel32.lib' => 1, 'oleaut32.lib' => 1, 'user32.lib' => 1, 'winspool.lib' => 1, 'gdi32.lib' => 1 ); my %opt_libraries = ( 'advapi32.lib' => 1, 'comdlg32.lib' => 1, 'winmm.lib' => 1 ); # maybe not this???? my %gl_libraries = ( 'opengl32.lib' => 1, 'glu32.lib' => 1 ); # AND maybe drop a library used twice where the second is just with a 'd' # appended, and maybe optionally remove all paths, and add any path # to the additional library directories @a = keys %adl; %adl = (); foreach $key (@a) { $key = trim_all($key); next if (length($key) == 0); @arr = split(/\s+/,$key); foreach $key (@arr) { $key = trim_all($key); if (length($key)) { $key = path_u2d($key); ($key,$d) = fileparse($key); # get the NAME only next if (length($key) == 0); $src = lc($key); next if (defined $win_libraries{$src}); if ($del_opt_libs) { next if (defined $opt_libraries{$src}); } if ($del_GL_libs) { next if (defined $gl_libraries{$src}); } $adl{$key} = 1; } } } if ($del_dbg_libs) { @a = keys %adl; @arr = (); foreach $key (@a) { ($n,$d,$ext) = fileparse($key, qr/\.[^.]*/); if ((length($n) > 2) && ($n =~ /d$/i)) { $n =~ s/d$//i; # remove trailing 'd' $src = $n.$ext; # get name without 'd' next if (defined $adl{$src}); # skip if we have that name } push(@arr,$key); } %adl = (); foreach $key (@arr) { next if (length($key) == 0); $adl{$key} = 1; } } @a = sort mycmp_nc_sort keys(%adl); $master_hash{$proj}->{libdeps} = [@a]; if (@a) { if (VERB9()) { prt("$proj: LibDeps: ".join(" ",@a)."\n"); } elsif (VERB2()) { my %h = (); foreach $key (@a) { $h{$key} = 1; } @a = sort mycmp_nc_sort keys(%h); prt("$proj: LibDeps: ".join(" ",@a)."\n"); } } # ==================================================================== # ==================================================================== # Additional LIBRARY directories @a = keys %ald; %ald = (); foreach $key (@a) { $key = trim_all($key); next if (length($key) == 0); @arr = split(";",$key); foreach $key (@arr) { $key = trim_all($key); if (length($key)) { $key = path_u2d($key); $ald{$key} = 1; } } } @a = sort mycmp_nc_sort keys(%ald); $master_hash{$proj}->{libdirs} = [@a]; if (@a) { prt("$proj: LibDirs: ".join(";",@a)."\n") if (VERB2()); } ###pgm_exit(1,""); } 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; $tot_files++; $tot_lines += $cnt; ($g_name,$g_sln_path,$g_ext) = fileparse( $fil, qr/\.[^.]*/ ); # 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=[$g_name] p=[$g_sln_path] ...\n" ) if (VERB2()); if ($proj_title eq 'temp') { $proj_title = $g_name; # this seems a better choice } $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( "[v9]: Got project [$tline] ...\n" ) if (VERB9); $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 $projid = strip_quotes(trim_all($arr[2])); # project ID $projff = fix_rel_path2($g_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, $g_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 { $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" ) if (VERB9); $cnt = 0; my $cmcnt = 0; foreach $projname (keys %sln_projects) { if (($projname eq 'ALL_BUILD')||($projname eq 'INSTALL')||($projname eq 'ZERO_CHECK')) { $cmcnt++; } else { $cnt++; } } prt( "Done $fil ... of ".scalar keys(%sln_projects)." items got $cnt project file(s)...\n" ) if (VERB9()); # 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 process_in_file($) { my ($inf) = @_; my ($file); my ($proj,$d,$e) = fileparse($inf, qr/\.[^.]*/ ); if (is_sln_ext($inf)) { my $rh = process_SLN_file2($inf); if (defined ${$rh}{'PROJECTS'}) { my $rph = ${$rh}{'PROJECTS'}; my @arr = sort keys(%{$rph}); my $cnt = 0; my $totcnt = scalar @arr; foreach $proj (@arr) { if ( !(($proj eq 'ALL_BUILD')||($proj eq 'INSTALL')||($proj eq 'ZERO_CHECK')) ) { $cnt++; } } prt("Of $totcnt items found $cnt project(s) in $inf\n"); $cnt = 0; foreach $proj (@arr) { $file = ${$rph}{$proj}; $cnt++; prt("\nProject:$cnt: $proj, File: $file\n") if (VERB9()); process_xml_file($file,$proj,$cnt); ### $load_log = 2; } } else { prt(Dumper($rh)); } } elsif (is_vcxproj_ext($inf)) { prt("\nProject: $proj, File: $inf\n"); # if (VERB9()); process_xml_file($inf,$proj,1); } else { prt("Can ONLY handle .sln or .vcxproj file, not [$e]! FIX ME!!!\n"); } } sub process_in_file_simp($) { my ($inf) = @_; if (! open INF, "<$inf") { pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); } my @lines = ; close INF; my $lncnt = scalar @lines; prt("Processing $lncnt lines, from [$inf]...\n"); my ($line,$inc,$lnn); $lnn = 0; foreach $line (@lines) { chomp $line; $lnn++; if ($line =~ /\s*#\s*include\s+(.+)$/) { $inc = $1; prt("$lnn: $inc\n"); } } } sub src_matching_proj($$$) { my ($proj,$ra,$rsrc) = @_; my ($src,$n,$d,$e); foreach $src (@{$ra}) { ($n,$d,$e) = fileparse($src, qr/\.[^.]*/ ); if ($n eq $proj) { ${$rsrc} = $src; return 1; } } return 0; } sub show_ref_hash($$$$) { my ($proj,$num,$typ,$rph) = @_; my ($ra,$cnt,$out,$src,$rh,$cnt2,$cnt3,$ri); my $inf = ${$rph}{'inputfile'}; my $target_incs = ''; my $cmake = "\n"; $cmake .= "# from $inf\n"; prt("\n") if (VERB1()); prt("$proj:$num: AppType: $typ, from $inf\n"); #$master_hash{$proj}->{sources} = [@a]; $ra = ${$rph}{'sources'}; $cnt = scalar @{$ra}; if (VERB2()) { prt("$proj:$num: Sources:\n".join("\n",@{$ra})."\n"); } elsif (VERB1()) { prt("$proj:$num: Sources: ".join(" ",@{$ra})."\n"); } $cnt2 = 0; if (defined ${$rph}{'headers'}) { $rh = ${$rph}{'headers'}; $cnt2 = scalar @{$rh}; if (VERB2()) { prt("$proj:$num: Headers:\n".join("\n",@{$rh})."\n"); } elsif (VERB1()) { prt("$proj:$num: Headers: ".join(" ",@{$rh})."\n"); } } elsif (VERB2()) { prt("$proj:$num: Headers: none\n"); } # aid: 'AdditionalIncludeDirectories' #$master_hash{$proj}->{addincs} = [@a]; $ri = ${$rph}{'addincs'}; $cnt3 = scalar @{$ri}; if ($cnt3) { # $target_incs = join(" ",@{$ri}); # $target_incs = path_d2u($target_incs); # target_include_directories( ${name} PRIVATE $ ) foreach $src (@{$ri}) { $src = path_d2u($src); $target_incs .= "\n "; } if (VERB2()) { prt("$proj:$num: AddIncs:\n".join("\n",@{$ri})."\n"); } elsif (VERB1()) { prt("$proj:$num: AddIncs: ".join(";",@{$ri})."\n"); } } if ($cnt) { my $ind = ' '; if (!src_matching_proj($proj,$ra,\$src)) { $src = ${$ra}[0]; # NO same named src - just use first } my ($n,$d) = fileparse($src); my $dir = path_d2u($d); $dir =~ s/\/$//; #strip trailing path sep. my $opt = "BUILD_".uc($proj); $opt =~ s/-/_/g; if ($add_options) { $cmake .= "if ($opt)\n"; $opt_list .= "option( $opt \"Set OFF to not build this component\" ON )\n"; } $cmake .= "set(name $proj)\n"; $cmake .= "set(dir $dir)\n"; # check me $include_dirs{$dir} = 1; $cmake .= "set( \$\{name\}_SRCS\n"; foreach $src (@{$ra}) { $src = path_d2u($src); ($n,$d) = fileparse($src); $d =~ s/\/$//; if ($d eq $dir) { $cmake .= $ind."\$\{dir\}/$n\n"; } else { $cmake .= $ind."$src\n"; } } $cmake .= "$ind)\n"; if ($cnt2) { $cmake .= "set( \$\{name\}_HDRS\n"; foreach $src (@{$rh}) { $src = path_d2u($src); ($n,$d) = fileparse($src); $d =~ s/\/$//; if ($d eq $dir) { $cmake .= $ind."\$\{dir\}/$n\n"; } else { $cmake .= $ind."$src\n"; } } $cmake .= "$ind)\n"; } if ($typ =~ /Library/i) { $out = \$libcmake; if ($cnt2) { $cmake .= "add_library( \$\{name\} \$\{LIB_TYPE\} \$\{\$\{name\}_SRCS\} \$\{\$\{name\}_HDRS\} )\n"; } else { $cmake .= "add_library( \$\{name\} \$\{LIB_TYPE\} \$\{\$\{name\}_SRCS\} )\n"; } if ($cnt3) { # aid: # 'AdditionalIncludeDirectories' $cmake .= "target_include_directories( \$\{name\} PRIVATE $target_incs\n )\n"; } $cmake .= "list(APPEND add_LIBS \$\{name\})\n"; $cmake .= "# deal with install, if any...\n"; $cmake .= "#install( TARGETS \$\{name\}\n"; $cmake .= "#".$ind."RUNTIME DESTINATION bin\n"; $cmake .= "#".$ind."LIBRARY DESTINATION lib\n"; $cmake .= "#".$ind."ARCHIVE DESTINATION lib )\n"; $cmake .= "#install(FILES \$\{\$\{name\}_HDRS\} DESTINATION include)\n"; } else { $out = \$execmake; if ($cnt2) { $cmake .= "add_executable( \$\{name\} \$\{\$\{name\}_SRCS\} \$\{\$\{name\}_HDRS\} )\n"; } else { $cmake .= "add_executable( \$\{name\} \$\{\$\{name\}_SRCS\})\n"; } if ($cnt3) { # aid: # 'AdditionalIncludeDirectories' $cmake .= "target_include_directories( \$\{name\} PRIVATE $target_incs)\n"; } $cmake .= "if(add_LIBS)\n"; $cmake .= "$ind target_link_libraries( \$\{name\} \${add_LIBS} )\n"; $cmake .= "endif ()\n"; $cmake .= "if (MSVC)\n"; $cmake .= "$ind set_target_properties( \$\{name\} PROPERTIES DEBUG_POSTFIX d )\n"; $cmake .= "endif ()\n"; $cmake .= "#install( TARGETS \$\{name\} DESTINATION bin )\n"; } if ($add_options) { $cmake .= "endif ($opt)\n"; } $cmake .= "\n"; ${$out} .= $cmake; } # $master_hash{$proj}->{preprocs} = [@a]; $ra = ${$rph}{'preprocs'}; prt("$proj:$num: PreProcs: ".join(";",@{$ra})."\n") if (VERB5()); #$master_hash{$proj}->{libdeps} = [@a]; $ra = ${$rph}{'libdeps'}; #prt("$proj: LibDeps: ".join(" ",@{$ra})."\n"); # if (VERB5()); #$master_hash{$proj}->{libdirs} = [@a]; $ra = ${$rph}{'libdirs'}; #prt("$proj: LibDirs: ".join(";",@{$ra})."\n"); # if (VERB5()); } sub show_master_hash($) { my $rh = shift; # ==================================================================== # A CONSOLE APP SHOWS: AppType: Application;Console # A WINDOWS APP SHOWS: AppType: Application;Windows # A SHARED DLL SHOWS: AppType: DynamicLibrary;Windows # A STATIC LIB SHOWS: AppType: StaticLibrary; #$master_hash{$proj}->{apptype} = $config;$subsystem; my @arr = sort mycmp_nc_sort keys(%{$rh}); my $cnt = scalar @arr; my ($proj,$rph,$typ,$ra); prt("\nshow_master_hash: $cnt projects, from '$in_file'...\n"); # static libs first my $num = 0; foreach $proj (@arr) { $rph = ${$rh}{$proj}; $typ = ${$rph}{'apptype'}; if ($typ =~ /Library/) { $num++; $tot_libs++; show_ref_hash($proj,$num,$typ,$rph); } } # show other than static libs foreach $proj (@arr) { $rph = ${$rh}{$proj}; $typ = ${$rph}{'apptype'}; if ( !($typ =~ /Library/) ) { $num++; $tot_exes++; show_ref_hash($proj,$num,$typ,$rph); } } } ######################################### ### MAIN ### parse_args(@ARGV); process_in_file($in_file); show_master_hash(\%master_hash); out_cmake_list(); pgm_exit(0,""); ######################################## sub need_arg { my ($arg,@av) = @_; pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av); } sub parse_args { my (@av) = @_; my ($arg,$sarg,@arr,$len,$tmp); while (@av) { $arg = $av[0]; if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if (($sarg =~ /^h/i)||($sarg eq '?')) { give_help(); pgm_exit(0,"Help exit(0)"); } elsif ($sarg =~ /^v/) { if ($sarg =~ /^v.*(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/) { $verbosity++; $sarg = substr($sarg,1); } } prt("Verbosity = $verbosity\n") if (VERB1()); } elsif ($sarg =~ /^l/) { if ($sarg =~ /^ll/) { $load_log = 2; } else { $load_log = 1; } prt("Set to load log at end. ($load_log)\n") if (VERB1()); } elsif ($sarg =~ /^o/) { need_arg(@av); shift @av; $sarg = $av[0]; $out_file = $sarg; prt("Set out file to [$out_file].\n") if (VERB1()); } elsif ($sarg =~ /^p/) { need_arg(@av); shift @av; $sarg = $av[0]; $proj_title = $sarg; prt("Set out project title to [$proj_title].\n") if (VERB1()); } elsif ($sarg =~ /^r/) { need_arg(@av); shift @av; $sarg = $av[0]; $rel_dir = File::Spec->rel2abs($sarg); if (-d $rel_dir) { prt("Set relative directory to [$rel_dir].\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Rel directory does NOT exist [$rel_dir]! [$sarg]\n"); } } elsif ($sarg =~ /^V/) { need_arg(@av); shift @av; $sarg = $av[0]; @arr = split(/\./,$sarg); $len = scalar @arr; if ($len < 3) { pgm_exit(1,"ERROR: Invalid version [$sarg]! Did not split in 3 on '.' - got $len?\n"); } $ver_maj = $arr[0]; $ver_min = $arr[1]; $ver_pt = $arr[2]; if ($len > 3) { $ver_rc = $arr[3]; } $ver_msg = "* check me *"; prt("Set version to '$ver_maj.$ver_min.$ver_pt\n") if (VERB1()); } elsif ($sarg =~ /^A/) { need_arg(@av); shift @av; $sarg = $av[0]; @arr = split(";",$sarg); $len = 0; foreach $tmp (@arr) { push(@add_inc_dirs,$tmp); $len++; } prt("Added $len include directories, to cmake.\n") if (VERB1()); } elsif ($sarg =~ /^O/) { $add_options = 1; prt("Set to add options around each component.\n") if (VERB1()); } elsif ($sarg =~ /^S/) { $add_static_runtime = 0; prt("Turned OFF the add static runtime option.\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n"); } } else { if (length($in_file) == 0) { $in_file = $arg; prt("Set input file to [$in_file]\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Already have an in file '$in_file'! What is this [$arg]!\n"); } } shift @av; } if ($debug_on) { prtw("WARNING: DEBUG is ON!\n"); if ((length($in_file) == 0) && $debug_on) { $in_file = $def_file; prt("Set DEFAULT input to [$in_file]\n"); $load_log = 2; } } if (length($in_file) == 0) { pgm_exit(1,"ERROR: No input files found in command!\n"); } if (! -f $in_file) { pgm_exit(1,"ERROR: Unable to find in file [$in_file]! Check name, location...\n"); } } sub give_help { prt("$pgmname: version $VERS\n"); prt("Usage: $pgmname [options] in-file\n"); prt("Options:\n"); prt(" --help (-h or -?) = This help, and exit 0.\n"); prt(" --verb[n] (-v) = Bump [or set] verbosity. def=$verbosity\n"); prt(" --load (-l) = Load LOG at end. ($outfile)\n"); prt(" --rel (-r) = Output sources relative to this directory.\n"); prt(" --out (-o) = Write cmake output to this file.\n"); prt(" --proj (-p) = Set the project name. (def=$proj_title)\n"); prt(" --VERS (-V) = Give version in dot.sep.form, maj.min.pts, like 1.2.3, to use in CMakeLists.txt.\n"); prt(" --ADD (-A) = Add these include directories, semi-colon sep, to cmake.\n"); prt(" --OPTIONS (-O) = Add an 'option' like if (BUILD_) around each component.\n"); prt(" --STATIC (-S) = Do NOT add the static runtime option. (def=$add_static_runtime)\n"); prt("\n"); prt(" Accept an input solution file, or a single .vcxproj, and process it,\n"); prt(" extracting separate projects, and their sources, and write a CMakeLists.txt\n"); prt(" to build the project(s).\n"); } # eof - showsln.pl