1: 2eval 'exec perl -wS $0 ${1+"$@"}' 3 if 0; 4#************************************************************** 5# 6# Licensed to the Apache Software Foundation (ASF) under one 7# or more contributor license agreements. See the NOTICE file 8# distributed with this work for additional information 9# regarding copyright ownership. The ASF licenses this file 10# to you under the Apache License, Version 2.0 (the 11# "License"); you may not use this file except in compliance 12# with the License. You may obtain a copy of the License at 13# 14# http://www.apache.org/licenses/LICENSE-2.0 15# 16# Unless required by applicable law or agreed to in writing, 17# software distributed under the License is distributed on an 18# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19# KIND, either express or implied. See the License for the 20# specific language governing permissions and limitations 21# under the License. 22# 23#************************************************************** 24 25 26# 27use XML::Parser; 28# ------------------------------------------------------------------------ 29# Other global stuff 30$is_debug=0; 31my $path = $ENV{'INPATH'} . "/"; 32my $quot = '"'; 33my %template_hash=(); 34my %vcproj_hash=(); 35# ------------------------------------------------------------------------ 36# Global stuff for parsing the *.vcproj files (XML::Parser) 37# 38my $ConfigurationGlobal = 1; # Release = 1, Debug=0 39my $Configuration = undef; 40my %configelements = (); 41my %files = (); 42my %files2copy = (); 43my %files_special = (); 44my $Release = 1; 45 # Release = 1, Debug = 0, undef = 2 46my $file_tmp = ""; # temporary storage for file name 47my $CustomSection = 0; 48# ------------------------------------------------------------------------ 49# ------------------------------------------------------------------------ 50# e.g. %object_hash with Key = blabla.cpp 51# contains a Hash: 52# Header: "..\\common\\unicode\\utypes.h ..\\common\\unicode\\uset.h" 53# CFlags: Common (set in templates file) or special sequence 54# CDefs: Common (set in templates file) or special sequence 55# ------------------------------------------------------------------------ 56my $configfile = shift; 57my $sourcePath = shift; 58if ( !$configfile ) { 59 $configfile = "createmak.cfg"; 60} 61if ( !$sourcePath ) { 62 $inpath = $ENV{"INPATH"}; 63 $sourcePath = $inpath . "\\misc\\build\\icu\\source"; 64} 65$dir = ""; 66$header = ""; 67$sep = "\\\\"; 68 69%project_by_id =(); 70%project_by_name = (); 71%project_dependencies = (); 72my @builddeps = prepare_allinone_all_mak(\%project_by_id,\%project_by_name,\%project_dependencies,$sourcePath); 73 74fillTemplateHash($configfile); 75 76create_allinone_all_mak(\@builddeps,\%project_by_id,$sourcePath); 77my @dirs = (); 78foreach $projectname(keys %project_by_name) 79{ 80 my $dir = $project_by_name{$projectname}[1]; 81 $dir =~ /\.\.\\(.+)\\(.+)\.vcproj/; 82 my $dir1 = $1; 83 my $dir2 = $2; 84 if ( $dir1 !~ /$dir2$/ ) { 85 $dir1 .= "\.$dir2"; 86 } 87 print "$dir1 - $dir2\n" if ($is_debug); 88 push @dirs, $dir1; 89} 90 91# set nonpro switch (linking against debug runtime if nonpro=1) 92my $nonpro = ($ENV{"PROEXT"} ne ".pro"); 93print "Non Product Build" if ($nonpro); 94 95foreach $dir(@dirs) 96{ 97 next if ($dir eq "data.makedata"); # very special don't overwrite this file 98 # ------------------------------------------------------------------------ 99 # Reset global stuff for parsing the *.vcproj files (XML::Parser) 100 # 101 $Configuration = $ConfigurationGlobal; # Release = 1, Debug=0 102 %configelements = (); 103 %files = (); 104 # contains all relevant *.c,*.cpp,*.h,*.rc files 105 %files2copy = (); 106 %files_special = (); 107 $Release = 2; 108 # Release = 1, Debug = 0, undef = 2 109 $file_tmp = ""; # temporary storage for file name 110 $CustomSection = 0; 111 # ------------------------------------------------------------------------ 112 113 my $extra_mak = ""; 114 ($dir, $extra_mak) = handle_extra_mak_files($dir); # handle e.g. tools/genrb.derb entires 115 116 my @mak=(); # Array for make file *.mak 117 my %deps=(); 118 my %object_hash=(); 119 my %collected_header=(); 120 my %collect_header_target_hash=(); 121 my %collect_object_target_hash=(); 122 my $vcproj_file = ""; 123 my $resource_file = ""; 124 125 # $dir : common,i18n,... 126 chomp $dir; 127 next if ( $dir eq "" ); 128 my $fullpath = $sourcePath . "\\" . $dir; 129 if ( $extra_mak eq "" ) { 130 if ($dir =~ /(.+)+\\(.+)$/) 131 { 132 $vcproj_file = $fullpath ."\\$2.vcproj"; 133 } else 134 { 135 $vcproj_file = $fullpath ."\\$dir.vcproj"; 136 } 137 } else 138 { 139 $vcproj_file = $fullpath . "\\" . $extra_mak . ".vcproj"; 140 } 141 142 143 # Parse the *.vcproj file 144 my $parser = new XML::Parser(ErrorContext => 2); 145 $parser->setHandlers(Start => \&start_handler, 146 Char => \&char_handler); 147 $parser->parsefile($vcproj_file); 148 if ( $file_tmp ) { 149 # save a file which hasn't been saved yet 150 $files{ $file_tmp } = 1; # save it now 151 $file_tmp = ""; # has been saved now reset it 152 } 153 154 # is there a resource file? 155 foreach $i (keys %files) 156 { 157 if ($i =~ /\.rc/) 158 { 159 $resource_file = $i; 160 } 161 } 162 # Fill hash %deps for dependencies for all files in directory ($testdir) 163 # %files contains all relevant files from *.vcproj 164 165 getAllFilesDeps($fullpath,\%deps,\%files); 166 my $includedir = $configelements{"Release"}{"OutputDirectory"}; # e.g. OutputDirectory = ..\..\lib 167 $includedir =~ s/lib/include/; 168 foreach $file( sort keys %deps) 169 { 170 $file =~ /(.+)\.(.+)/; 171 my $name = $1; 172 my $ext = $2; 173 next if (!defined $name); 174 $object = "\$(INTDIR)\\" . "$name.obj"; 175 $collect_object_target_hash{$object}=1; 176 177 createMakDepSection($dir,$name,$ext,$deps{$file},\@mak,\%files_special); 178 } 179 my %all_target_hash=(); 180 foreach $header(sort keys %files2copy) 181 { 182 my $dir; 183 my $file; 184 #$pathdepth = "..\\.."; 185 $file = $header; 186 $header =~ s/^\.\\//; 187 $inputpath = $file; 188 $target = $includedir . "\\" . $header; 189 $target =~ /.+\\(.+)\\.+$/; 190 $targetpath = $configelements{"Release"}{"CommandLine"}; 191 chomp $targetpath; 192 # set %all_target_hash and @mak 193 createCopySection($file,$inputpath,$target,$targetpath,\@mak,\%all_target_hash); 194 $collect_header_target_hash{$target}=1; 195 } 196 my $test = $configelements{"Release"}{"OutputFile"}; 197 $all_target_hash{$test}=1; 198 199 # set name of the *.mak file 200 my $mak_file=""; 201 if ( $extra_mak eq "" ) { 202 $mak_file = $vcproj_file; 203 $mak_file =~ s/vcproj/mak/; 204 } else 205 { 206 # extra_mak eg. derb, stringperf 207 $mak_file = $fullpath . "\\$extra_mak" . "\.mak"; 208 } 209 210 # generate the content of the *.mak file 211 # in @mak array 212 print "extra_mak=$extra_mak\n" if ($is_debug); 213 print "mak_file=$mak_file\n" if ($is_debug); 214 open(MAKFILE, ">$mak_file") || die "Can't open $mak_file\n"; 215 print_all_target($fullpath, \%all_target_hash); 216 217 # $extra_mak handles further *.mak files in a directory 218 print_flags($dir,$extra_mak,'CFlags',$nonpro); # depends on directory 219 print_simple_flag("Rules"); 220 print_simple_flag("Link"); 221 print_common_linkflags(); 222# print_flags($fullpath,$extra_mak,'LinkFlags'); # depends on directory 223# print_lib32_objs($fullpath,$extra_mak,\%collect_object_target_hash,$resource_file); 224 print_flags($dir,$extra_mak,'LinkFlags'); # depends on directory 225 print_lib32_objs($dir,$extra_mak,\%collect_object_target_hash,$resource_file); 226 227 # write @mak array into the *.mak file 228 foreach $line(@mak) 229 { 230 print MAKFILE $line; 231 } 232 $|=1; 233 print "."; # user entertainment 234 $|=0; 235} 236print "\ndone\n"; 237exit; 238 239############################################################################ 240sub getKey #01.04.2008 09:46 241############################################################################ 242 { 243 my $line = shift; 244 $line =~ /\[(.+)\]/; 245 return $1; 246} ##getKey 247 248############################################################################ 249sub fillTemplateHash #01.04.2008 10:48 250############################################################################ 251 { 252 my $file = shift; 253 open (TEMPLATE, "< $file") || die "Can't open template file $file\n"; 254 my $key = ""; 255 while ( $line=<TEMPLATE> ) { 256 if ( $line =~ /\[.+\]/ ) { 257 print $line if ($is_debug); 258 if ( $key ne "" ) { 259 $template_hash{$key}=[@cmdlines]; 260 @cmdlines=""; 261 $key=""; 262 } 263 $key = getKey( $line ); 264 } else 265 { 266 push @cmdlines, $line; 267 } 268 } # while 269} ##fillTemplateHash 270 271############################################################################ 272sub createCopySection #01.04.2008 11:37 273############################################################################ 274 { 275 my $header = shift; 276 my $inputpath = shift; 277 my $target = shift; 278 my $targetpath = shift; 279 my $ref_make_file = shift; # Array written later to make file *.mak 280 my $ref_all_target_hash = shift; # reference to fill all_target_hash; 281 if ( $target !~ /\\include/ && $target !~ /\\bin/) { 282 return; # $target contains nonsense 283 } 284 if ( !$targetpath ) { 285 # $targetpath is empty! (Due to missing entry in *.vcproj file) 286 # Generate $targetpath here from $target 287 my $t = $target; 288 $t =~ /(.+)\\(.+)$/; 289 $targetpath = "copy \"\$(InputPath)\" " . $1; 290 chomp $targetpath; 291 } 292 $targetpath =~ s/\r$//; # remove x0A from EOL if the is one 293 my @template = @{$template_hash{"Copy"}}; 294 my $line = ""; 295 foreach $line(@template) 296 { 297 $line =~ s/<HEADER>/$header/g; 298 $line =~ s/<INPUTPATH>/$inputpath/g; 299 $line =~ s/<TARGET>/$target/g; 300 $line =~ s/<TARGETPATH>/$targetpath/; 301 push @{$ref_make_file}, $line; # from template 302 $$ref_all_target_hash{$target} = 1; # "\"$target\" "; 303 # save for target ALL: 304 } 305} ##createCopySection 306 307############################################################################ 308sub createMakDepSection #01.04.2008 13:36 309############################################################################ 310 { 311 # creates the dependency section in the make file 312 my $dir = shift; 313 my $source = shift; 314 my $extension = shift; 315 my $ref_header_list = shift; 316 my $ref_make_file = shift; # Array written later to make file *.mak 317 my $ref_special_file = shift; # hash for special files (compiler flags, include paths) 318 my $header_list = ""; 319 my $special_flag = 0; 320 321 return if ( !defined $source ); 322 foreach $header(@{$ref_header_list}) 323 { 324 if ( ($header =~ /^\.\.\\.+/) && (-e $header )) { 325 $header_list = $header_list . " " . $header; # this header is located in an other directory 326 } else 327 { 328 $header_list = $header_list . " .\\" . $header; 329 } 330 } 331 332 #special handling 333 # compile this file with other compiler switches 334 my $file = $source . "\." . $extension; 335 $dir =~ s/\\/_/; 336 my @template = @{$template_hash{"CFlags_$dir"}}; 337 if ( defined $$ref_special_file{"AdditionalIncludeDirectories"}{$file} ) { 338 $special_flag = 1; 339 my $includepath = $$ref_special_file{"AdditionalIncludeDirectories"}{$file}; 340 $includepath =~ s/\;/\/I /g; # subst ; with /I for multiple paths 341 $line = "CPP_SWITCH_INCLUDE=/I $includepath\n"; 342 push @{$ref_make_file}, $line; 343 foreach $line(@template) 344 { 345 if ( $line =~ /CPP_PROJ/) 346 { 347 $line =~ s/CPP_PROJ=/CPPX_PROJ=/; 348 $line =~ s/\$\(CDEFS\)/\$\(CDEFS\) \$\(CPP_SWITCH_INCLUDE\)/; # include $(CPP_SWITCH_INCLUDE) 349 push @{$ref_make_file}, $line; 350 } 351 } 352 } 353 if ( $$ref_special_file{"DisableLanguageExtensions"}{$file} ) 354 { 355 # FALSE = /Ze 356 $special_flag = 1; 357 foreach $line(@template) 358 { 359 if ( $line =~ /CPP_PROJ/) 360 { 361 $line =~ s/CPP_PROJ=/CPPX_PROJ=/; 362 $line =~ s/-Za/-Ze/; 363 if ( $nonpro ) 364 { 365 # if non product link against debug libraries 366 $line =~ s/-MD/-MDd/; 367 $line =~ s/-MT/-MTd/; 368 } 369 push @{$ref_make_file}, $line; 370 } 371 } 372 } 373 374 @template = @{$template_hash{"Deps"}}; 375 my $line = ""; 376 foreach $line(@template) 377 { 378 $line =~ s/<SOURCEFILE>/$source/g; 379 $line =~ s/<EXT>/$extension/g; 380 $line =~ s/<HEADER_LIST>/$header_list/g; 381 push @{$ref_make_file}, $line; 382 } 383 384 if ( $special_flag ) 385 { 386 pop @{$ref_make_file}; # remove empty line 387 push @{$ref_make_file},"\t\$(CPP) @<<\n"; 388 push @{$ref_make_file},"\t\$(CPPX_PROJ) \$(SOURCE)\n"; 389 push @{$ref_make_file},"<<\n\n"; 390 $special_flag = 0; 391 } 392 393} ##createMakDepSection 394 395 396############################################################################ 397sub getFilenameFromPath #10.04.2008 13:03 398############################################################################ 399{ 400 my $path = shift; 401 $path =~ /.+\\(.+)$/; 402 return $1; 403} ##getFilenameFromPath 404 405############################################################################ 406sub getAllFilesDeps #08.04.2008 09:39 407############################################################################ 408{ 409 my $path = shift; 410 my $ref_deps = shift; 411 my $ref_allfiles = shift; # contains all relevant files from *.vcproj 412 my %local_header_hash=(); # contains all local header 413 414 my @all_files = keys %{$ref_allfiles}; 415 416 # collect lokal header names in %header_hash 417 foreach $file(@all_files) 418 { 419 if ( $file =~ /.+\.h/ ) { 420 chomp $file; 421 $local_header_hash{$file} = 1; 422 } 423 } 424 425 foreach $file(@all_files) 426 { 427 my @header_deps=(); 428 my $skip = 0; 429 430 $file =~ s/^\.\\//; # remove leading .\ 431 432 # exclude sub directories and several file extensions 433 # *.dep,*.h,*.in,*.mak,*.pl,*.txt,*.vcproj.*.rc and origs of patch files (*.*~) and 434 # .cvsignore (files beginning with .) 435 next if ( (-d "$path$sep$file") || ($file =~ /.+(_|\~|dep|h|in|mak|pl|txt|vcproj|rc)$/) || ($file =~ /^\.+./)); 436 parse_header_deps($path,$file,\@header_deps,\%local_header_hash); 437 handle_dep_to_other_directory($path,$file,\@header_deps,$$ref_vcproj{$file}) if ($$ref_vcproj{$file}); 438 $$ref_deps{$file}=[@header_deps]; 439 } 440} ##getAllFilesDeps 441 442 ############################################################################ 443 sub parse_header_deps #14.06.2006 18:04 444 ############################################################################ 445 { 446 # get includes from c/cpp file 447 # call create_deps(path,file,\$link_obj) 448 # 449 my $path = shift; 450 my $cfile = shift; 451 my $ref_header_deps = shift; 452 my $ref_local_header_hash = shift; 453 454 my $fullpath = $path . $sep . $cfile; 455 my $unicodedep=""; 456 open(IN, "<$fullpath") || die "can't open $fullpath\n"; 457 while ( $line = <IN> ) { 458 next if ($line !~ /^.?\#include.+/); # handle include lines only 459 if ($line =~ /.+?\s(.+)/) 460 { 461 $header = $1; 462 if ( ($header !~ /^<.+/) && ($header !~ /.+\.c.+$/) ) { 463 # no <stdio> etc. header 464 $header =~ s/\s+\/\*.+\*\///; # delete <blanks>/* ... */ 465 $header =~ s/\s+\/\/.+//; # delete <blanks>//...... 466 $header =~ s/\//\\/; # subst. / with \ 467 $header =~ s/^\"/\".\\/; 468 $header =~ s/\"//g; 469 $header =~ s/\.\\//; 470 my $test = $$ref_local_header_hash{$header}; 471 my $header_fullpath = $path . "\\" . $header; 472 if ( $test || (($header =~ /\\/) && (-e $header_fullpath))) { 473 push @{$ref_header_deps}, $header; 474 } 475 } 476 } 477 } 478 } ##parse_header_deps 479 480############################################################################ 481sub handle_dep_to_other_directory #16.04.2008 15:11 482############################################################################ 483{ 484 # there has been an additional include directoy detected 485 # now try to find out which header (parsed from c/cpp-file) 486 # comes from this directory by checking: does it exist there? 487 my $path = shift; 488 my $file = shift; 489 my $ref_header_deps = shift; 490 my $path_additional = shift; 491 my $search_path = $path . "\\" . $path_additional; 492 my $counter = 0; 493 foreach $header(@{$ref_header_deps}) 494 { 495 my $full_path = $search_path . "\\" . $header; 496 if ( -e "$full_path" ) 497 { 498 $$ref_header_deps[$counter] = $path_additional . "\\" . $header; 499 } 500 $counter++ 501 } 502} ##handle_dep_to_other_directory 503 504############################################################################ 505sub print_lib32_objs #18.04.2008 12:54 506############################################################################ 507 { 508 # generate Link section 509 my $path = shift; 510 my $extra_mak = shift; 511 my $ref_objecthash = shift; 512 my $resource_file = shift; 513 # output link objects 514 print MAKFILE "LINK32_OBJS= \\\n"; 515 # print objects 516 foreach $object(sort keys %{$ref_objecthash}) 517 { 518 print MAKFILE "\t$object \\\n"; 519 } 520 521 # print *.res if *.rc exists 522 if ( $resource_file ne "" ) { 523 my $res_file = $resource_file; 524 $res_file =~ s/\.rc/\.res/; 525 $res_file =~ /(.+)\\(.+)$/; 526 $res_file = $2; 527 print MAKFILE "\t\$(INTDIR)\\$res_file \\\n"; 528 } 529 530 # add import libs and res files 531 print_flags($path,$extra_mak,"AdditionalLinkObjects"); 532 my $outfile = $configelements{"Release"}{"OutputFile"}; 533 534 # section for linking 535 print_link_template($path,$outfile); 536 537 # section for creating res files 538 # setting for rsc, res target etc. 539 print "resource_file=$resource_file\n" if ($is_debug); 540 print_rsc_template($resource_file) if ($resource_file); 541 print_simple_flag("Special_extra_uconv") if ($outfile =~ /uconv/); 542} ##print_lib32_objs 543 544############################################################################ 545sub print_all_target #26.06.2008 13:27 546############################################################################ 547 { 548 my $path = shift; 549 my $ref_all_target_hash = shift; 550 my $filename = getFilenameFromPath($path); 551 my $outdir = $configelements{"Release"}{"OutputDirectory"}; 552 print MAKFILE "NULL=\n"; 553 print MAKFILE "OUTDIR=$outdir\n"; 554 print MAKFILE "OutDir=$outdir\n"; 555 print MAKFILE "INTDIR=.\\Release\n\n"; 556 print MAKFILE "ALL: "; 557 foreach $target(sort keys %{$ref_all_target_hash}) 558 { 559 if ( $target =~ /\.exe/ ) { 560 my $out = $target; 561 $out =~ s/.\\Release/\.\.\\\.\.\\\.\.\\bin/; 562 $out =~ s/\$\(OutDir\)/\.\.\\\.\.\\\.\.\\bin/; 563 $out =~ s/\//\\/; # convert / to \ 564 $target = $out; 565 } 566 print MAKFILE "\"$target\" "; 567 } 568 569 # Append [Target_<dir>] item e.g. ../../icuxy36.dll 570 my $targetkey = "Target_" . $filename; 571 my @target = (); 572 if ( exists $template_hash{$targetkey} ) { 573 @target = @{$template_hash{$targetkey}}; 574 } 575 my $additional_target=""; 576 foreach $additional_target(@target) 577 { 578 print MAKFILE $additional_target if ($additional_target ne ""); 579 } 580 print MAKFILE "\n\n"; 581 print MAKFILE "\"\$(OUTDIR)\" : \n"; 582 print MAKFILE "\tif not exist \"\$(OUTDIR)/\$(NULL)\" mkdir \"\$(OUTDIR)\"\n\n"; 583 print MAKFILE "!IF \"\$(OUTDIR)\" != \"\$(INTDIR)\"\n"; 584 print MAKFILE "\"\$(INTDIR)\" : \n"; 585 print MAKFILE "\tif not exist \"\$(INTDIR)/\$(NULL)\" mkdir \"\$(INTDIR)\"\n"; 586 print MAKFILE "!ENDIF\n"; 587 print MAKFILE "\n\n"; 588} ##print_all_target 589 590############################################################################ 591sub print_simple_flag #18.04.2008 13:39 592############################################################################ 593{ 594 my $simple_flag = shift; 595 my @template = @{$template_hash{$simple_flag}}; 596 foreach $line(@template) 597 { 598 print MAKFILE $line; 599 } 600} ##print_rules 601 602############################################################################ 603sub print_link_template #18.04.2008 13:39 604############################################################################ 605{ 606 my $dir = shift; 607 my $outfile = shift; 608 my $manifest; 609 # set resource id for manifest file 610 if ( $outfile =~ /\.exe/ ) { 611 $manifest = 1; 612 } else 613 { 614 $manifest = 2; 615 } 616 my @template = (); 617 if ($dir =~ /stubdata/ ) { 618 @template = @{$template_hash{"Special_stubdata"}}; 619 } else 620 { 621 @template = @{$template_hash{"LinkTemplate"}}; 622 } 623 624 print MAKFILE "\n"; # insert blank line 625 foreach $line(@template) 626 { 627 $line =~ s/<OUTFILE>/$outfile/; 628 $line =~ s/<MANIFEST>/$manifest/; 629 print MAKFILE $line; 630 } 631 632 # insert special stuff for 633 # extras/uconv/uconv.mak 634 if ( $dir =~ /uconv/ ) { 635 print_flags($dir,"","Special"); 636 } 637 638 # for *.exe files an additional 639 # copy section is required to get 640 # the stuff into the global bin directory 641 my %dummy = (); 642 my @mak = (); 643 if( $manifest ==1 ) 644 { 645 # source,inputpath,target,action 646 my $out = $outfile; 647 $out =~ s/.\\.*Release/\.\.\\\.\.\\\.\.\\bin/; 648 $out =~ s/\$\(OutDir\)/\.\.\\\.\.\\\.\.\\bin/; 649 $out =~ s/\//\\/; # subst / with \ 650 $outfile =~ s/\//\\/; # subst / with \ 651 createCopySection($outfile,$outfile,$out,"copy \"\$(InputPath)\" .\\..\\..\\..\\bin",\@mak,\%dummy); 652 foreach $line(@mak) 653 { 654 print MAKFILE $line; 655 } 656 } 657} ##print_rules 658 659############################################################################ 660sub print_rsc_template #04.11.2008 14:48 661############################################################################ 662 { 663 # print resource compiler setting + resource target 664 my $resourcefile = shift; 665 # skip this if no res file required 666 667 return if (!$resourcefile); 668 $resfile = $resourcefile; 669 #remove file extension (.res) 670 $resfile =~ /(.+)\\(.+)\.(.+)/; 671 $resfile = $2; 672 673 my @template = @{$template_hash{"RSC_Template"}}; 674 print MAKFILE "\n"; # insert blank line 675 foreach $line(@template) 676 { 677 $line =~ s/<FILE>/$resourcefile/; 678 $line =~ s/<FILEOUT>/$resfile/; 679 print MAKFILE $line; 680 } 681} ##print_rsc_template 682 683############################################################################ 684sub print_flags #18.04.2008 14:19 685############################################################################ 686{ 687 # CFlags, LinkFlags 688 my $dir = shift; 689 my $extra_mak = shift; # eg. derb.mak, stringperf.mak 690 my $flag = shift; 691 my $nonpro = shift; 692 my @template = (); 693 my $switch = ""; 694 $dir =~ s/\\/_/g if ($dir); # change \ to _ 695 $switch = "$flag" . "_" . "$dir" if ($dir); 696 handle_CFlags() if ($flag eq "CFlags"); # get and print Preprocessor defines 697 $switch .= "\." . $extra_mak if ( $extra_mak ne "" ) ; 698 if ( exists $template_hash{$switch} ) { 699 @template = @{$template_hash{$switch}}; 700 foreach $line(@template) 701 { 702 if ( $nonpro ) 703 { 704 # if non product link against debug libraries 705 $line =~ s/-MD/-MDd/; 706 $line =~ s/-MT/-MTd/; 707 } 708 print MAKFILE $line; 709 } 710 } 711} ##print_flags 712 713############################################################################ 714sub handle_CFlags #28.01.2009 11:20 715############################################################################ 716 { 717 718 my $ppdefs = $configelements{"Release"}{"PreprocessorDefinitions"}; 719 my $ppinc = $configelements{"Release"}{"AdditionalIncludeDirectories"}; 720 my @template = @{$template_hash{"General_CFlags"}}; 721 $ppdefs =~ s/;/ -D/g; # subst ; with -D switch 722 $ppdefs = "-D" . $ppdefs; 723 $ppinc =~ s/(;|,)/ -I/g; # subst ; with -I switch 724 $ppinc = "-I" . $ppinc; 725 print "ppdefs=$ppdefs\n" if ($is_debug); 726 print "ppinc =$ppinc\n" if ($is_debug); 727 foreach $line(@template) 728 { 729 $line =~ s/<AddIncDirs>/$ppinc/; 730 $line =~ s/<PreProcDefs>/$ppdefs/; 731 print MAKFILE $line; 732 } 733} ##handle_CFlags 734 735############################################################################ 736sub print_common_linkflags #21.11.2008 11:47 737############################################################################ 738 { 739 my @template = @{$template_hash{"CommonLinkFlags"}}; 740 my $outfile = $configelements{"Release"}{"OutputFile"}; 741 my $pdbfile = $configelements{"Release"}{"ProgramDatabaseFile"}; 742 $pdbfile =~ s/\//\\/; # subst / with \ 743 $outfile =~ s/\//\\/; # subst / with \ 744 print "PATH=$path OUTFILE=$outfile\n" if ($is_debug); 745 foreach $line(@template) 746 { 747 $line =~ s/<OUTFILE>/$outfile/; 748 $line =~ s/<PDBFILE>/$pdbfile/; 749 print MAKFILE $line; 750 } 751} ##print_common_linkflags 752 753############################################################################ 754sub handle_extra_mak_files #25.08.2008 14:32 755############################################################################ 756{ 757 # extract extra filename for *.mak file 758 # e.g input: tools\genrb.derb 759 # output: derb 760 my $direntry = shift; 761 my $out = ""; 762 my $dir = ""; 763 if ( $direntry =~ /(.+)\.(.+)$/ ) { 764 $dir = $1; 765 $out = $2; 766 } else 767 { 768 $dir = $direntry; 769 } 770 return ($dir,$out); 771} ##handle_extra_mak_files 772 773############################################################################ 774sub prepare_allinone_all_mak 775############################################################################ 776{ 777 # Read in allinone.sln 778 # Fills hashes and returns an array with build order 779 # uses topographical sorting 780 781 my $href_project_by_id = shift; 782 my $href_project_by_name = shift; 783 my $href_project_dependencies = shift; 784 my $sourcePath = shift; 785 786 my $allslnfile = $sourcePath . "\\allinone\\allinone.sln"; 787 my @projectdeps; 788 my $projectname; 789 my $projectpath; 790 my $projectid; 791 792 # fill hash tables 793 open (SLN, "< $allslnfile") || die "Can't open $allslnfile\n"; 794 while ($line = <SLN>) 795 { 796 my @project = (); 797 if ( $line =~ /^Project\(/ ) { 798 @project = split( /,/, $line); 799 if ( $#project ) { 800 $projectname = ""; 801 $projectpath = ""; 802 $projectid = ""; 803 @projectdeps = (); 804 my @subarray = (); 805 @subarray = split( /=/, $project[0]); 806 $projectname = $subarray[1]; 807 $projectname =~ s/\"//g; # remove " 808 $projectpath = $project[1]; 809 $projectid = $project[2]; 810 $projectid =~ s/\"//g; # remove " 811 $projectid =~ s/.+\{//g; # remove til { 812 $projectid =~ s/\}\n//g; # remove }<CR> 813 my @pnp = ($projectname,$projectpath); 814 my @pip = ($projectid,$projectpath); 815 $$href_project_by_id{$projectid}=[@pnp]; 816 $$href_project_by_name{$projectname} =[@pip]; 817 } 818 } # $line =~ /^Project\(/ 819 if ( $line =~ /ProjectSection\(/ ) { 820 $psect = 1; 821 next; 822 } 823 if ( $line =~ /EndProjectSection/ ) { 824 $psect = 0; 825 $$href_project_dependencies{$projectid}=[@projectdeps]; 826 next; 827 } 828 if ( $psect ) { 829 my @tarray = split(/=/, $line); 830 $depends_on_id = $tarray[0]; 831 $depends_on_id =~ s/.+\{//g; 832 $depends_on_id =~ s/\}.+//g; 833 print "+$depends_on_id-\n" if ($is_debug); 834 835 push @projectdeps, $depends_on_id; 836 } 837 } 838 ######################################## 839 # sort here and generate build order 840 ######################################## 841 $objektzahl=0; 842 %hashindex=(); 843 844 foreach $projectid(keys %{$href_project_by_id}) 845 { 846 if ( $$href_project_dependencies{$projectid} ) 847 { 848 @deps = @{$$href_project_dependencies{$projectid}}; 849 } else 850 { 851 @deps = (); 852 } 853 for $counter(0..$#deps) 854 { 855 $v = find_or_create_element($deps[$counter]); 856 $n = find_or_create_element($projectid); 857 push @{$nachfolgerliste[$v]},$n; 858 } 859 } 860 861 for $n (0..$objektzahl-1) 862 { 863 $vorgaengerzahl[$n]=0; 864 } 865 for $v (0..$objektzahl-1) 866 { 867 for $n (@{$nachfolgerliste[$v]}) 868 { 869 ++$vorgaengerzahl[$n]; 870 } 871 } 872 873 @hilfsliste=(); 874 for $n (0..$objektzahl-1) 875 { 876 push(@hilfsliste,$n) if ($vorgaengerzahl[$n]==0) 877 } 878 879 $ausgabe=0; 880 @builddep =(); 881 while (defined($v=pop(@hilfsliste))) 882 { 883 push @builddep, $name[$v]; # save build order by project_id; 884 ++$ausgabe; 885 for $n (@{$nachfolgerliste[$v]}) 886 { 887 --$vorgaengerzahl[$n]; 888 push(@hilfsliste,$n) if ($vorgaengerzahl[$n]==0); 889 } 890 } # while 891 die "Cyclic dependencies found! Stopping now.\n" if $ausgabe<$objektzahl; 892 ############################################################## 893 # End of sorting stuff 894 ############################################################## 895 896 return @builddep; 897 ############################################################### 898 ########################### 899 # sub for sorting only 900 ########################### 901 sub find_or_create_element 902 { 903 my ($str)=@_; 904 my ($idx)=$hashindex{$str}; 905 if (!defined($idx)) { # new element ... 906 $idx=$objektzahl++; 907 $hashindex{$str}=$idx; 908 $name[$idx]=$str; 909 @{$nachfolgerliste[$idx]}=(); 910 } 911 return $idx; 912 } # find_or_create_element 913} # prepare_allinone_all_mak 914 915############################################################################ 916sub create_allinone_all_mak #09.02.2009 09:22 917############################################################################ 918{ 919 my $ref_buildorder = shift; 920 my $href_project_by_id = shift; 921 my $sourcePath = shift; 922 my $allmakfile = $sourcePath . "\\allinone\\all.mak"; 923 open (ALLMAK, ">$allmakfile") || die "Can't write to $allmakfile \n"; 924 print ALLMAK "ALL: "; 925 foreach $proj(@{$ref_buildorder}) 926 { 927 print ALLMAK $$href_project_by_id{$proj}[0]; 928 } 929 print ALLMAK "\n\n"; 930 931 foreach $proj( @{$ref_buildorder} ) 932 { 933 print "$proj $$href_project_by_id{$proj}[0] $$href_project_by_id{$proj}[1]\n"; 934 my $prjdir = $$href_project_by_id{$proj}[1]; 935 $prjdir =~ /(.+)\\(.+)$/; 936 $prjdir = $1; 937 $prjname = $2; 938 $prjdir =~ s/^.+\"//; 939 $prjname =~ s/\"$//; 940 $prjname =~ s/vcproj/mak/; 941 $allinonehelpstring = $prjdir; 942 $allinonehelpstring =~ s/^\.+\\//; # remove ..\ 943 my $backcount = ""; 944 while ($allinonehelpstring=~ /.+\\/g) # counts the occuring \ 945 { 946 $backcount .= "..\\"; 947 } 948 $allinonedir = $backcount . "..\\allinone"; 949 950 # write all.mak 951 $$href_project_by_id{$proj}[0] =~ s/^\s+//; 952 if ( $$href_project_by_id{$proj}[0] ne "makedata" ) 953 { 954 my @template = @{$template_hash{"AllInOnePrj"}}; 955 foreach $line(@template) 956 { 957 $line =~ s/<PRJ>/$$href_project_by_id{$proj}[0]/; 958 $line =~ s/<PRJDIR>/$prjdir/; 959 $line =~ s/<PRJMAK>/$prjname/; 960 $line =~ s/<ALLINONEDIR>/$allinonedir/; 961 print ALLMAK $line; 962 } 963 } else 964 { 965 #special code snippet 966 print ALLMAK "makedata : \n"; 967 print ALLMAK " cd \"..\\data\"\n"; 968 print ALLMAK " nmake /f makedata.mak icumake=\$(MAKEDIR)\\..\\data cfg=Release\n"; 969 print ALLMAK " cd \"..\\allinone\"\n\n"; 970 } 971 } 972 close ALLMAK; 973} ##create_allinone_all_mak 974 975############################################################################ 976 977# ------------------------------------------------------------------------ 978# XML parser handling 979# ------------------------------------------------------------------------ 980 981############################################################################ 982sub start_handler 983############################################################################ 984{ 985 my $p = shift; # pointer to parser 986 my $el = shift; # element 987 988 # Deal with attributes 989 990 my $CompilerSection = 0; 991 my $LinkerSection = 0; 992 my $ConfigSection = ($el eq "Configuration"); 993 994 while (@_) 995 { 996 # shift if ( $el eq "FileConfiguration" ); 997 my $att = shift; 998 my $val = shift; 999 $CustomSection = 0; 1000 if ($special_file && defined $att & $att ne "Name") 1001 { 1002 print "$special_file - $att - $val\n"; 1003 my @param = ($att,$val); 1004 $files_special{ $special_file } = [@param]; # files with special compiler switch 1005 @test = @{$files_special{ $special_file }}; 1006 print "test=@test\n"; 1007 $special_file=""; 1008 } 1009 if ( $ConfigSection && $att eq "Name" && $val eq "Release|Win32" ) { 1010 $Release = 1; 1011 $config = "Release"; # Release 1012 } 1013 if ( $ConfigSection && $att eq "Name" && $val eq "Debug|Win32" ) { 1014 $Release = 0; # Debug 1015 $config = "Debug"; 1016 } 1017 if ( $att eq "Name" && $val eq "VCCLCompilerTool" ) { 1018 $CompilerSection = 1; 1019 } 1020 if ( $att eq "Name" && $val eq "VCLinkerTool" ) { 1021 $LinkerSection = 1; 1022 } 1023 if ( $att eq "Name" && $val eq "VCCustomBuildTool" ) { 1024 $CustomSection = 1; 1025 } 1026 1027 # For Configuration Infos like compiler defines etc. 1028 if ( $att eq "PreprocessorDefinitions" && $CompilerSection ) { 1029 $configelements{$config}{$att} = $val; 1030 } 1031 if ( $att eq "AdditionalIncludeDirectories" && $CompilerSection ) { 1032 #$configelements{$config}{$att} = $val; 1033 if ( ($file_tmp ne "") && ($val ne "") ) { 1034 $files{ $file_tmp } = 1; # save it now 1035 $file_tmp =~ s/^\.\\//; # remove leading .\ 1036 $files_special{"AdditionalIncludeDirectories"}{$file_tmp} = $val; 1037 print "Include $val: $file_tmp\n" if ($is_debug); 1038 $file_tmp = ""; # has been saved now reset it 1039 } else 1040 { 1041 $configelements{$config}{$att} = $val; 1042 } 1043 } 1044 if ( ($att eq "DisableLanguageExtensions") && $CompilerSection ) { 1045 #$configelements{$config}{$att} = $val; 1046 if ( ($file_tmp ne "") && ($val ne "")) { 1047 $files{ $file_tmp } = 1; # save it now 1048 $file_tmp =~ s/^\.\\//; # remove leading .\ 1049 $files_special{"DisableLanguageExtensions"}{$file_tmp} = $val; 1050 print "-Ze: $file_tmp\n" if ($is_debug); 1051 $file_tmp = ""; # has been saved now reset it 1052 } 1053 } 1054 if ( $att eq "OutputDirectory" ) { 1055 $configelements{$config}{$att} = $val; 1056 } 1057 if ( $att eq "OutputFile" && $LinkerSection ) { 1058 $configelements{$config}{$att} = $val; 1059 } 1060 if ( $att eq "ProgramDatabaseFile" ) { 1061 $configelements{$config}{$att} = $val; 1062 } 1063 if ( $att eq "ImportLibrary" && $LinkerSection ) { 1064 $configelements{$config}{$att} = $val; 1065 } 1066 if ($att eq "CommandLine") { 1067 $configelements{$config}{$att} = $val; 1068 } 1069 if (($att eq "PreprocessorDefinitions") && $ConfigSection) { 1070 $configelements{$config}{$att} = $val; 1071 } 1072 1073 # Is the file in the step before a header 1074 # which has to be copied into the global 1075 # include path? 1076 if ( $file_tmp ne "" ) 1077 { 1078 $config = "Release"; 1079 if ( ($att eq "CommandLine") && ($el eq "Tool") ) 1080 { 1081 if ( $file_tmp =~ /.+\.h$/ ) { 1082 $files2copy{ $file_tmp } = $val; # unicode + layout header to copy 1083 $file_tmp = ""; # has been saved now reset it 1084 } 1085 } 1086 } # if $file_tmp 1087 1088 # For files 1089 if ( $att eq "RelativePath" ) { 1090 if ( $file_tmp ) { 1091 # no special file (include dir / compiler switch) 1092 $files{ $file_tmp } = 1; # save it now 1093 $file_tmp = ""; # has been saved now reset it 1094 } 1095 # store temporary the file name 1096 $file_tmp = $val if ($val !~ /\.mk$/); # no *.mk files 1097 } 1098 } # while @_ 1099} # End start_handler 1100 1101############################################################################ 1102sub char_handler 1103############################################################################ 1104{ 1105} # End char_handler 1106