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