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